From 32a44360e06cb3b871a32b46b4bd66e429c9258f Mon Sep 17 00:00:00 2001 From: Patrick Owen Date: Fri, 3 May 2024 22:40:43 -0400 Subject: [PATCH 01/10] Configure Vulkan with yakui prerequisites --- client/src/graphics/base.rs | 6 +++++- client/src/graphics/core.rs | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/client/src/graphics/base.rs b/client/src/graphics/base.rs index e3aa6fb2..0007c8da 100644 --- a/client/src/graphics/base.rs +++ b/client/src/graphics/base.rs @@ -139,7 +139,11 @@ impl Base { .queue_create_infos(&[vk::DeviceQueueCreateInfo::default() .queue_family_index(queue_family_index) .queue_priorities(&[1.0])]) - .enabled_extension_names(&device_exts), + .enabled_extension_names(&device_exts) + .push_next( + &mut vk::PhysicalDeviceDescriptorIndexingFeatures::default() + .descriptor_binding_partially_bound(true), + ), None, ) .unwrap(), diff --git a/client/src/graphics/core.rs b/client/src/graphics/core.rs index 377a35ed..5341b166 100644 --- a/client/src/graphics/core.rs +++ b/client/src/graphics/core.rs @@ -68,7 +68,7 @@ impl Core { .application_version(0) .engine_name(name) .engine_version(0) - .api_version(vk::make_api_version(0, 1, 1, 0)); + .api_version(vk::make_api_version(0, 1, 2, 0)); let mut instance_info = vk::InstanceCreateInfo::default() .application_info(&app_info) .enabled_extension_names(&exts); From e1015b9a771dd67f26f0a7381d367da9e209e745 Mon Sep 17 00:00:00 2001 From: Patrick Owen Date: Sat, 4 May 2024 12:09:19 -0400 Subject: [PATCH 02/10] Add first round of yakui boilerplate --- client/Cargo.toml | 2 ++ client/src/graphics/base.rs | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/client/Cargo.toml b/client/Cargo.toml index bfe13572..d00ff005 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -14,6 +14,8 @@ server = { path = "../server" } tracing = "0.1.10" ash = { version = "0.38.0", default-features = false, features = ["loaded", "debug", "std"] } lahar = { git = "https://github.com/Ralith/lahar", rev = "7963ae5750ea61fa0a894dbb73d3be0ac77255d2" } +yakui = { git = "https://github.com/SecondHalfGames/yakui", rev = "2eda113392712e87eb1c372b7d495edc29b8ccdc" } +yakui-vulkan = { git = "https://github.com/SecondHalfGames/yakui", rev = "2eda113392712e87eb1c372b7d495edc29b8ccdc" } winit = "0.29.10" ash-window = "0.13" raw-window-handle = "0.6" diff --git a/client/src/graphics/base.rs b/client/src/graphics/base.rs index 0007c8da..fab1814b 100644 --- a/client/src/graphics/base.rs +++ b/client/src/graphics/base.rs @@ -6,6 +6,7 @@ use std::path::PathBuf; use std::sync::Arc; use std::{fs, io}; use tracing::{error, info, trace, warn}; +use yakui_vulkan::{VulkanContext, YakuiVulkan}; use ash::{vk, Device}; @@ -36,6 +37,8 @@ pub struct Base { pub timestamp_bits: u32, pipeline_cache_path: Option, debug_utils: Option, + // Yakui Vulkan context + pub yakui_vulkan: yakui_vulkan::YakuiVulkan, } unsafe impl Send for Base {} @@ -44,6 +47,7 @@ unsafe impl Sync for Base {} impl Drop for Base { fn drop(&mut self) { unsafe { + self.yakui_vulkan.cleanup(&self.device); self.device .destroy_pipeline_cache(self.pipeline_cache, None); self.device.destroy_render_pass(self.render_pass, None); @@ -274,6 +278,14 @@ impl Base { .as_ref() .map(|_| debug_utils::Device::new(&core.instance, &device)); + let mut yakui_vulkan_options = yakui_vulkan::Options::default(); + yakui_vulkan_options.render_pass = render_pass; + let mut yakui_vulkan = YakuiVulkan::new( + &VulkanContext::new(&device, queue, memory_properties), + yakui_vulkan_options, + ); + yakui_vulkan.transfers_submitted(); + Some(Self { core, physical, @@ -289,6 +301,7 @@ impl Base { limits: physical_properties.properties.limits, timestamp_bits: queue_family_properties.timestamp_valid_bits, debug_utils, + yakui_vulkan, }) } } From adeac113e248d36c409f70385b3c0f6906f6d419 Mon Sep 17 00:00:00 2001 From: Patrick Owen Date: Sat, 4 May 2024 18:28:54 -0400 Subject: [PATCH 03/10] Move YakuiVulkan into draw to allow mutable access --- client/src/graphics/base.rs | 13 ------------- client/src/graphics/draw.rs | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/client/src/graphics/base.rs b/client/src/graphics/base.rs index fab1814b..0007c8da 100644 --- a/client/src/graphics/base.rs +++ b/client/src/graphics/base.rs @@ -6,7 +6,6 @@ use std::path::PathBuf; use std::sync::Arc; use std::{fs, io}; use tracing::{error, info, trace, warn}; -use yakui_vulkan::{VulkanContext, YakuiVulkan}; use ash::{vk, Device}; @@ -37,8 +36,6 @@ pub struct Base { pub timestamp_bits: u32, pipeline_cache_path: Option, debug_utils: Option, - // Yakui Vulkan context - pub yakui_vulkan: yakui_vulkan::YakuiVulkan, } unsafe impl Send for Base {} @@ -47,7 +44,6 @@ unsafe impl Sync for Base {} impl Drop for Base { fn drop(&mut self) { unsafe { - self.yakui_vulkan.cleanup(&self.device); self.device .destroy_pipeline_cache(self.pipeline_cache, None); self.device.destroy_render_pass(self.render_pass, None); @@ -278,14 +274,6 @@ impl Base { .as_ref() .map(|_| debug_utils::Device::new(&core.instance, &device)); - let mut yakui_vulkan_options = yakui_vulkan::Options::default(); - yakui_vulkan_options.render_pass = render_pass; - let mut yakui_vulkan = YakuiVulkan::new( - &VulkanContext::new(&device, queue, memory_properties), - yakui_vulkan_options, - ); - yakui_vulkan.transfers_submitted(); - Some(Self { core, physical, @@ -301,7 +289,6 @@ impl Base { limits: physical_properties.properties.limits, timestamp_bits: queue_family_properties.timestamp_valid_bits, debug_utils, - yakui_vulkan, }) } } diff --git a/client/src/graphics/draw.rs b/client/src/graphics/draw.rs index eb7139eb..81e25c91 100644 --- a/client/src/graphics/draw.rs +++ b/client/src/graphics/draw.rs @@ -50,6 +50,8 @@ pub struct Draw { /// Miscellany character_model: Asset, + /// Yakui Vulkan context + pub yakui_vulkan: yakui_vulkan::YakuiVulkan, } /// Maximum number of simultaneous frames in flight @@ -188,6 +190,14 @@ impl Draw { }, ); + let mut yakui_vulkan_options = yakui_vulkan::Options::default(); + yakui_vulkan_options.render_pass = gfx.render_pass; + let mut yakui_vulkan = yakui_vulkan::YakuiVulkan::new( + &yakui_vulkan::VulkanContext::new(device, gfx.queue, gfx.memory_properties), + yakui_vulkan_options, + ); + yakui_vulkan.transfers_submitted(); + Self { gfx, cfg, @@ -209,6 +219,7 @@ impl Draw { image_barriers: Vec::new(), character_model, + yakui_vulkan, } } } @@ -262,6 +273,12 @@ impl Draw { present: vk::Semaphore, frustum: &Frustum, ) { + let _yakui_vulkan_context = yakui_vulkan::VulkanContext::new( + &self.gfx.device, + self.gfx.queue, + self.gfx.memory_properties, + ); + let draw_started = Instant::now(); let view = sim.as_ref().map_or_else(Position::origin, |sim| sim.view()); let projection = frustum.projection(1.0e-4); @@ -546,6 +563,7 @@ impl Drop for Draw { voxels.destroy(device); } } + self.yakui_vulkan.cleanup(&self.gfx.device); device.destroy_command_pool(self.cmd_pool, None); device.destroy_query_pool(self.timestamp_pool, None); device.destroy_descriptor_pool(self.common_descriptor_pool, None); From 48abcc0f9d736c83d8c59a8ce0841189ee240277 Mon Sep 17 00:00:00 2001 From: Patrick Owen Date: Sat, 4 May 2024 19:32:55 -0400 Subject: [PATCH 04/10] Add text to screen: first attempt --- client/src/graphics/draw.rs | 35 ++++++++++++++++++++++++++++------- client/src/graphics/window.rs | 1 + 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/client/src/graphics/draw.rs b/client/src/graphics/draw.rs index 81e25c91..6ba10d4c 100644 --- a/client/src/graphics/draw.rs +++ b/client/src/graphics/draw.rs @@ -52,6 +52,8 @@ pub struct Draw { character_model: Asset, /// Yakui Vulkan context pub yakui_vulkan: yakui_vulkan::YakuiVulkan, + /// Yakui context + pub yak: yakui::Yakui, } /// Maximum number of simultaneous frames in flight @@ -220,6 +222,7 @@ impl Draw { character_model, yakui_vulkan, + yak: yakui::Yakui::new(), } } } @@ -273,12 +276,6 @@ impl Draw { present: vk::Semaphore, frustum: &Frustum, ) { - let _yakui_vulkan_context = yakui_vulkan::VulkanContext::new( - &self.gfx.device, - self.gfx.queue, - self.gfx.memory_properties, - ); - let draw_started = Instant::now(); let view = sim.as_ref().map_or_else(Position::origin, |sim| sim.view()); let projection = frustum.projection(1.0e-4); @@ -290,6 +287,24 @@ impl Draw { let state = &mut self.states[self.next_state]; let cmd = state.cmd; + let yakui_vulkan_context = yakui_vulkan::VulkanContext::new( + device, + self.gfx.queue, + self.gfx.memory_properties, + ); + + self.yak.set_surface_size([extent.width as f32, extent.height as f32].into()); + self.yak.set_unscaled_viewport(yakui::geometry::Rect::from_pos_size( + Default::default(), + [extent.width as f32, extent.height as f32].into(), + )); + + self.yak.start(); + yakui::text(96.0, "Hello world!"); + self.yak.finish(); + + let paint = self.yak.paint(); + // We're using this state again, so put the fence back in the unsignaled state and compute // the next frame to use device.reset_fences(&[state.fence]).unwrap(); @@ -357,6 +372,9 @@ impl Draw { ); timestamp_index += 1; + self.yakui_vulkan.transfers_finished(&yakui_vulkan_context); + self.yakui_vulkan.transfer(paint, &yakui_vulkan_context, cmd); + // Schedule transfer of uniform data. Note that we defer actually preparing the data to just // before submitting the command buffer so time-sensitive values can be set with minimum // latency. @@ -483,9 +501,12 @@ impl Draw { } } + // TODO + self.yakui_vulkan.paint(paint, &yakui_vulkan_context, cmd, extent); + device.cmd_next_subpass(cmd, vk::SubpassContents::INLINE); - self.fog.draw(device, state.common_ds, cmd); + //self.fog.draw(device, state.common_ds, cmd); // Finish up device.cmd_end_render_pass(cmd); diff --git a/client/src/graphics/window.rs b/client/src/graphics/window.rs index 866726c2..005c461e 100644 --- a/client/src/graphics/window.rs +++ b/client/src/graphics/window.rs @@ -366,6 +366,7 @@ impl Window { } Err(e) => panic!("queue_present: {e}"), }; + draw.yakui_vulkan.transfers_submitted(); } } } From da58f40aca167e1e868ef4c70ccebabb9e556936 Mon Sep 17 00:00:00 2001 From: Patrick Owen Date: Sat, 4 May 2024 21:43:22 -0400 Subject: [PATCH 05/10] Render on the second subpass --- client/Cargo.toml | 4 ++-- client/src/graphics/draw.rs | 31 ++++++++++++++++--------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/client/Cargo.toml b/client/Cargo.toml index d00ff005..3506ac5c 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -14,8 +14,8 @@ server = { path = "../server" } tracing = "0.1.10" ash = { version = "0.38.0", default-features = false, features = ["loaded", "debug", "std"] } lahar = { git = "https://github.com/Ralith/lahar", rev = "7963ae5750ea61fa0a894dbb73d3be0ac77255d2" } -yakui = { git = "https://github.com/SecondHalfGames/yakui", rev = "2eda113392712e87eb1c372b7d495edc29b8ccdc" } -yakui-vulkan = { git = "https://github.com/SecondHalfGames/yakui", rev = "2eda113392712e87eb1c372b7d495edc29b8ccdc" } +yakui = { git = "https://github.com/SecondHalfGames/yakui", rev = "cbac6c06dbf948268df6d9e93346788e977cbef3" } +yakui-vulkan = { git = "https://github.com/SecondHalfGames/yakui", rev = "cbac6c06dbf948268df6d9e93346788e977cbef3" } winit = "0.29.10" ash-window = "0.13" raw-window-handle = "0.6" diff --git a/client/src/graphics/draw.rs b/client/src/graphics/draw.rs index 6ba10d4c..cca89cef 100644 --- a/client/src/graphics/draw.rs +++ b/client/src/graphics/draw.rs @@ -194,6 +194,7 @@ impl Draw { let mut yakui_vulkan_options = yakui_vulkan::Options::default(); yakui_vulkan_options.render_pass = gfx.render_pass; + yakui_vulkan_options.subpass = 1; let mut yakui_vulkan = yakui_vulkan::YakuiVulkan::new( &yakui_vulkan::VulkanContext::new(device, gfx.queue, gfx.memory_properties), yakui_vulkan_options, @@ -287,17 +288,16 @@ impl Draw { let state = &mut self.states[self.next_state]; let cmd = state.cmd; - let yakui_vulkan_context = yakui_vulkan::VulkanContext::new( - device, - self.gfx.queue, - self.gfx.memory_properties, - ); + let yakui_vulkan_context = + yakui_vulkan::VulkanContext::new(device, self.gfx.queue, self.gfx.memory_properties); - self.yak.set_surface_size([extent.width as f32, extent.height as f32].into()); - self.yak.set_unscaled_viewport(yakui::geometry::Rect::from_pos_size( - Default::default(), - [extent.width as f32, extent.height as f32].into(), - )); + self.yak + .set_surface_size([extent.width as f32, extent.height as f32].into()); + self.yak + .set_unscaled_viewport(yakui::geometry::Rect::from_pos_size( + Default::default(), + [extent.width as f32, extent.height as f32].into(), + )); self.yak.start(); yakui::text(96.0, "Hello world!"); @@ -373,7 +373,8 @@ impl Draw { timestamp_index += 1; self.yakui_vulkan.transfers_finished(&yakui_vulkan_context); - self.yakui_vulkan.transfer(paint, &yakui_vulkan_context, cmd); + self.yakui_vulkan + .transfer(paint, &yakui_vulkan_context, cmd); // Schedule transfer of uniform data. Note that we defer actually preparing the data to just // before submitting the command buffer so time-sensitive values can be set with minimum @@ -501,12 +502,12 @@ impl Draw { } } - // TODO - self.yakui_vulkan.paint(paint, &yakui_vulkan_context, cmd, extent); - device.cmd_next_subpass(cmd, vk::SubpassContents::INLINE); - //self.fog.draw(device, state.common_ds, cmd); + self.fog.draw(device, state.common_ds, cmd); + + self.yakui_vulkan + .paint(paint, &yakui_vulkan_context, cmd, extent); // Finish up device.cmd_end_render_pass(cmd); From cc6efcbe79fb9027486743d5dd106c3463ecbb97 Mon Sep 17 00:00:00 2001 From: Patrick Owen Date: Sat, 4 May 2024 21:57:42 -0400 Subject: [PATCH 06/10] Support two in-flight frames --- client/src/graphics/draw.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/graphics/draw.rs b/client/src/graphics/draw.rs index cca89cef..e5f19ff1 100644 --- a/client/src/graphics/draw.rs +++ b/client/src/graphics/draw.rs @@ -200,6 +200,7 @@ impl Draw { yakui_vulkan_options, ); yakui_vulkan.transfers_submitted(); + yakui_vulkan.transfers_submitted(); Self { gfx, From e444dc5b34758a8b27f0229ac85344332aff6b4f Mon Sep 17 00:00:00 2001 From: Patrick Owen Date: Sat, 4 May 2024 23:19:25 -0400 Subject: [PATCH 07/10] Use PIPELINE_DEPTH instead of manually repeating code --- client/src/graphics/draw.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/graphics/draw.rs b/client/src/graphics/draw.rs index e5f19ff1..2df458f9 100644 --- a/client/src/graphics/draw.rs +++ b/client/src/graphics/draw.rs @@ -199,8 +199,9 @@ impl Draw { &yakui_vulkan::VulkanContext::new(device, gfx.queue, gfx.memory_properties), yakui_vulkan_options, ); - yakui_vulkan.transfers_submitted(); - yakui_vulkan.transfers_submitted(); + for _ in 0..PIPELINE_DEPTH { + yakui_vulkan.transfers_submitted(); + } Self { gfx, From a5b05977914b3cb7cdb04c03804acda9826531aa Mon Sep 17 00:00:00 2001 From: Patrick Owen Date: Sun, 5 May 2024 14:22:06 -0400 Subject: [PATCH 08/10] Replace the cursor with a yakui element --- client/shaders/fog.frag | 10 ++-------- client/src/graphics/draw.rs | 3 +++ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/client/shaders/fog.frag b/client/shaders/fog.frag index 37ef0048..e8cf9da2 100644 --- a/client/shaders/fog.frag +++ b/client/shaders/fog.frag @@ -16,12 +16,6 @@ void main() { float view_length = length(view_pos); // Convert to true hyperbolic distance, taking care to respect atanh's domain float dist = view_length >= 1.0 ? INFINITY : atanh(view_length); - if (dot(scaled_view_pos.xy, scaled_view_pos.xy) < 0.0001) { - // Temporary code to add a cursor in the center of the window for placing/breaking blocks - // TODO: Replace with a UI element when UI exists - fog = vec4(0.0, 0.0, 0.0, 0.0); - } else { - // Exponential^k fog - fog = vec4(0.5, 0.65, 0.9, exp(-pow(dist * fog_density, 5))); - } + // Exponential^k fog + fog = vec4(0.5, 0.65, 0.9, exp(-pow(dist * fog_density, 5))); } diff --git a/client/src/graphics/draw.rs b/client/src/graphics/draw.rs index 2df458f9..4dfe30a8 100644 --- a/client/src/graphics/draw.rs +++ b/client/src/graphics/draw.rs @@ -303,6 +303,9 @@ impl Draw { self.yak.start(); yakui::text(96.0, "Hello world!"); + yakui::align(yakui::Alignment::CENTER, || { + yakui::colored_box(yakui::Color::BLACK.with_alpha(0.9), [5.0, 5.0]); + }); self.yak.finish(); let paint = self.yak.paint(); From 8bba2b5b1534037f12bf7661deee336d97c1cc28 Mon Sep 17 00:00:00 2001 From: Patrick Owen Date: Sun, 5 May 2024 14:54:22 -0400 Subject: [PATCH 09/10] Indicate the selected material --- client/src/graphics/draw.rs | 19 +++++++++++++++---- client/src/sim.rs | 4 ++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/client/src/graphics/draw.rs b/client/src/graphics/draw.rs index 4dfe30a8..ba11e129 100644 --- a/client/src/graphics/draw.rs +++ b/client/src/graphics/draw.rs @@ -5,6 +5,7 @@ use ash::vk; use common::traversal; use lahar::Staged; use metrics::histogram; +use yakui::Color; use super::{fog, voxels, Base, Fog, Frustum, GltfScene, Meshes, Voxels}; use crate::{Asset, Config, Loader, Sim}; @@ -302,10 +303,20 @@ impl Draw { )); self.yak.start(); - yakui::text(96.0, "Hello world!"); - yakui::align(yakui::Alignment::CENTER, || { - yakui::colored_box(yakui::Color::BLACK.with_alpha(0.9), [5.0, 5.0]); - }); + if let Some(sim) = sim.as_ref() { + // Cursor + yakui::align(yakui::Alignment::CENTER, || { + yakui::colored_box(yakui::Color::BLACK.with_alpha(0.9), [5.0, 5.0]); + }); + + yakui::align(yakui::Alignment::TOP_LEFT, || { + yakui::pad(yakui::widgets::Pad::all(8.0), || { + yakui::colored_box_container(Color::BLACK.with_alpha(0.7), || { + yakui::label(format!("Selected material: {:?}", sim.selected_material())); + }); + }); + }); + } self.yak.finish(); let paint = self.yak.paint(); diff --git a/client/src/sim.rs b/client/src/sim.rs index 8abfe08c..9f59582f 100644 --- a/client/src/sim.rs +++ b/client/src/sim.rs @@ -161,6 +161,10 @@ impl Sim { self.selected_material = *MATERIAL_PALETTE.get(idx).unwrap_or(&MATERIAL_PALETTE[0]); } + pub fn selected_material(&self) -> Material { + self.selected_material + } + pub fn set_break_block_pressed_true(&mut self) { self.break_block_pressed = true; } From e59f81eee7a4a006c2c09778839d5bc737bbb9e7 Mon Sep 17 00:00:00 2001 From: Patrick Owen Date: Sun, 5 May 2024 15:48:02 -0400 Subject: [PATCH 10/10] Move GUI code to a separate module --- client/src/graphics/draw.rs | 17 ++++------------ client/src/graphics/gui.rs | 37 +++++++++++++++++++++++++++++++++++ client/src/graphics/mod.rs | 1 + client/src/graphics/window.rs | 7 +++++++ 4 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 client/src/graphics/gui.rs diff --git a/client/src/graphics/draw.rs b/client/src/graphics/draw.rs index ba11e129..52c97dd4 100644 --- a/client/src/graphics/draw.rs +++ b/client/src/graphics/draw.rs @@ -5,8 +5,8 @@ use ash::vk; use common::traversal; use lahar::Staged; use metrics::histogram; -use yakui::Color; +use super::gui::{self, GuiState}; use super::{fog, voxels, Base, Fog, Frustum, GltfScene, Meshes, Voxels}; use crate::{Asset, Config, Loader, Sim}; use common::proto::{Character, Position}; @@ -271,9 +271,11 @@ impl Draw { /// /// Submits commands that wait on `image_acquired` before writing to `framebuffer`'s color /// attachment. + #[allow(clippy::too_many_arguments)] // Every argument is of a different type, making this less of a problem. pub unsafe fn draw( &mut self, mut sim: Option<&mut Sim>, + gui_state: &GuiState, framebuffer: vk::Framebuffer, depth_view: vk::ImageView, extent: vk::Extent2D, @@ -304,18 +306,7 @@ impl Draw { self.yak.start(); if let Some(sim) = sim.as_ref() { - // Cursor - yakui::align(yakui::Alignment::CENTER, || { - yakui::colored_box(yakui::Color::BLACK.with_alpha(0.9), [5.0, 5.0]); - }); - - yakui::align(yakui::Alignment::TOP_LEFT, || { - yakui::pad(yakui::widgets::Pad::all(8.0), || { - yakui::colored_box_container(Color::BLACK.with_alpha(0.7), || { - yakui::label(format!("Selected material: {:?}", sim.selected_material())); - }); - }); - }); + gui::gui(gui_state, sim); } self.yak.finish(); diff --git a/client/src/graphics/gui.rs b/client/src/graphics/gui.rs new file mode 100644 index 00000000..ecd51f97 --- /dev/null +++ b/client/src/graphics/gui.rs @@ -0,0 +1,37 @@ +use yakui::{ + align, colored_box, colored_box_container, label, pad, widgets::Pad, Alignment, Color, +}; + +use crate::Sim; + +pub struct GuiState { + show_gui: bool, +} + +impl GuiState { + pub fn new() -> Self { + GuiState { show_gui: true } + } + + pub fn toggle_gui(&mut self) { + self.show_gui = !self.show_gui; + } +} + +pub fn gui(gui_state: &GuiState, sim: &Sim) { + if !gui_state.show_gui { + return; + } + + align(Alignment::CENTER, || { + colored_box(Color::BLACK.with_alpha(0.9), [5.0, 5.0]); + }); + + align(Alignment::TOP_LEFT, || { + pad(Pad::all(8.0), || { + colored_box_container(Color::BLACK.with_alpha(0.7), || { + label(format!("Selected material: {:?}", sim.selected_material())); + }); + }); + }); +} diff --git a/client/src/graphics/mod.rs b/client/src/graphics/mod.rs index 83622d0c..d39cd9ae 100644 --- a/client/src/graphics/mod.rs +++ b/client/src/graphics/mod.rs @@ -6,6 +6,7 @@ mod draw; mod fog; mod frustum; mod gltf_mesh; +mod gui; mod meshes; mod png_array; pub mod voxels; diff --git a/client/src/graphics/window.rs b/client/src/graphics/window.rs index 005c461e..c9b806a5 100644 --- a/client/src/graphics/window.rs +++ b/client/src/graphics/window.rs @@ -15,6 +15,7 @@ use winit::{ window::{CursorGrabMode, Window as WinitWindow, WindowBuilder}, }; +use super::gui::GuiState; use super::{Base, Core, Draw, Frustum}; use crate::Net; use crate::{net, Config, Sim}; @@ -57,6 +58,7 @@ pub struct Window { swapchain_needs_update: bool, draw: Option, sim: Option, + gui_state: GuiState, net: Net, } @@ -93,6 +95,7 @@ impl Window { swapchain_needs_update: false, draw: None, sim: None, + gui_state: GuiState::new(), net, } } @@ -261,6 +264,9 @@ impl Window { sim.toggle_no_clip(); } } + KeyCode::F1 if state == ElementState::Pressed => { + self.gui_state.toggle_gui(); + } KeyCode::Escape => { let _ = self.window.set_cursor_grab(CursorGrabMode::None); self.window.set_cursor_visible(true); @@ -352,6 +358,7 @@ impl Window { // Render the frame draw.draw( self.sim.as_mut(), + &self.gui_state, frame.buffer, frame.depth_view, swapchain.state.extent,