diff --git a/Cargo.toml b/Cargo.toml index c0cf813..de197ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,10 @@ members = ["kubi", "kubi-server", "kubi-shared", "kubi-udp"] resolver = "2" +[profile.release-with-debug] +inherits = "release" +debug = true + [profile.dev] opt-level = 1 diff --git a/kubi/shaders/gui/progress.vert b/kubi/shaders/gui/progress.vert deleted file mode 100644 index 82ad5d7..0000000 --- a/kubi/shaders/gui/progress.vert +++ /dev/null @@ -1,13 +0,0 @@ -#version 150 core - -in vec2 position; -in vec2 uv; -out vec2 v_uv; -uniform vec2 ui_scale; -uniform vec2 element_position; -uniform vec2 element_size; - -void main() { - v_uv = uv; - gl_Position = vec4(ui_scale * (element_position + (position * element_size)), 0.0, 1.0); -} diff --git a/kubi/shaders/gui/progress.frag b/kubi/shaders/gui/progressbar.frag similarity index 100% rename from kubi/shaders/gui/progress.frag rename to kubi/shaders/gui/progressbar.frag diff --git a/kubi/shaders/gui/progressbar.vert b/kubi/shaders/gui/progressbar.vert new file mode 100644 index 0000000..d57292c --- /dev/null +++ b/kubi/shaders/gui/progressbar.vert @@ -0,0 +1,12 @@ +#version 150 core + +in vec2 position; +out vec2 uv; +uniform vec2 ui_view; +uniform vec2 element_position; +uniform vec2 element_size; + +void main() { + uv = position; + gl_Position = vec4(ui_view * (element_position + (position * element_size)), 0.0, 1.0); +} diff --git a/kubi/src/block_placement.rs b/kubi/src/block_placement.rs index 3eff4be..a0f3991 100644 --- a/kubi/src/block_placement.rs +++ b/kubi/src/block_placement.rs @@ -1,7 +1,7 @@ use shipyard::{UniqueViewMut, UniqueView, View, IntoIter, ViewMut, EntitiesViewMut}; use crate::{ player::MainPlayer, - world::{raycast::LookingAtBlock, ChunkStorage, block::Block, queue::{BlockUpdateQueue, BlockUpdateEvent}}, + world::{raycast::LookingAtBlock, block::Block, queue::{BlockUpdateQueue, BlockUpdateEvent}}, input::{Inputs, PrevInputs}, events::{EventComponent, player_actions::PlayerActionEvent}, }; diff --git a/kubi/src/color.rs b/kubi/src/color.rs new file mode 100644 index 0000000..1854ff4 --- /dev/null +++ b/kubi/src/color.rs @@ -0,0 +1,12 @@ +use glam::{Vec4, vec4}; + +#[inline(always)] +pub fn color_rgba(r: u8, g: u8, b: u8, a: u8) -> Vec4 { + vec4(r as f32 / 255., g as f32 / 255., b as f32 / 255., a as f32 / 255.) +} + +#[inline(always)] +pub const fn color_hex(c: u32) -> Vec4 { + let c = c.to_le_bytes(); + vec4(c[0] as f32, c[1] as f32, c[2] as f32, c[3] as f32) +} diff --git a/kubi/src/gui.rs b/kubi/src/gui.rs index 68f99b2..2230e2b 100644 --- a/kubi/src/gui.rs +++ b/kubi/src/gui.rs @@ -1,3 +1,75 @@ -//TODO +use shipyard::{Component, Unique, Workload, IntoWorkload, AllStoragesView, AllStoragesViewMut}; +use glam::{Vec2, Vec4, vec2}; +use crate::color::color_hex; + pub mod text_widget; pub mod progressbar; + +use progressbar::{render_progressbars, ProgressbarComponent}; + +//TODO compute gui scale on window resize +#[derive(Unique, Clone, Copy, Debug)] +pub struct GuiViewScale(pub Vec2); + +#[derive(Component, Clone, Copy, Debug, Default)] +pub struct GuiComponent; + +#[derive(Component, Clone, Copy, Debug)] +#[track(All)] +pub struct GuiTransform { + pub position: Vec2, + pub scale: Vec2, +} +impl Default for GuiTransform { + fn default() -> Self { + Self { + position: Vec2::ZERO, + scale: Vec2::ONE, + } + } +} + +#[derive(Component, Clone, Copy, Debug)] +pub struct PrimaryColor(pub Vec4); +impl Default for PrimaryColor { + fn default() -> Self { + Self(color_hex(0x156cdd)) + } +} + +#[derive(Component, Clone, Copy, Debug)] +pub struct SecondaryColor(pub Vec4); +impl Default for SecondaryColor { + fn default() -> Self { + Self(color_hex(0xc9d5e4)) + } +} + +pub fn render_gui() -> Workload { + ( + render_progressbars + ).into_workload() +} + +pub fn init_gui( + storages: AllStoragesView, +) { + storages.add_unique(GuiViewScale(Vec2::ONE)); +} + +pub fn gui_testing( + mut storages: AllStoragesViewMut, +) { + storages.add_entity(( + GuiComponent, + GuiTransform { + position: Vec2::ZERO, + scale: vec2(1.0, 0.05), + }, + ProgressbarComponent { + progress: 0.5 + }, + PrimaryColor::default(), + SecondaryColor::default(), + )); +} diff --git a/kubi/src/gui/progressbar.rs b/kubi/src/gui/progressbar.rs index e69de29..847c584 100644 --- a/kubi/src/gui/progressbar.rs +++ b/kubi/src/gui/progressbar.rs @@ -0,0 +1,47 @@ +use shipyard::{UniqueView, UniqueViewMut, NonSendSync, View, Component, IntoIter}; +use glium::{Surface, uniform, DrawParameters}; +use crate::{ + prefabs::ProgressbarShaderPrefab, + rendering::{ + RenderTarget, + primitives::rect::RectPrimitive + }, +}; +use super::{GuiComponent, GuiTransform, PrimaryColor, SecondaryColor, GuiViewScale}; + +#[derive(Component, Debug, Clone, Copy, Default)] +pub struct ProgressbarComponent { + pub progress: f32 +} + +pub fn render_progressbars( + mut target: NonSendSync>, + rect: NonSendSync>, + program: NonSendSync>, + view: UniqueView, + components: View, + transforms: View, + progressbars: View, + primary: View, + secondary: View, +) { + for (_, transform, progress, pri, sec) in (&components, &transforms, &progressbars, &primary, &secondary).iter() { + //TODO do this properly + let pri = Some(pri).copied(); + let sec = Some(sec).copied(); + target.0.draw( + &rect.0, + &rect.1, + &program.0, + &uniform! { + element_position: transform.position.to_array(), + element_size: transform.scale.to_array(), + ui_view: view.0.to_array(), + progress: progress.progress, + color: pri.unwrap_or_default().0.to_array(), + bg_color: sec.unwrap_or_default().0.to_array(), + }, + &DrawParameters::default() + ).unwrap(); + } +} diff --git a/kubi/src/gui/text_widget.rs b/kubi/src/gui/text_widget.rs index e69de29..31c4422 100644 --- a/kubi/src/gui/text_widget.rs +++ b/kubi/src/gui/text_widget.rs @@ -0,0 +1 @@ +//TODO text widget diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 14772f3..0440b0b 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -34,11 +34,13 @@ pub(crate) mod state; pub(crate) mod gui; pub(crate) mod networking; pub(crate) mod init; +pub(crate) mod color; use world::{ init_game_world, loading::{update_loaded_world_around_player, switch_to_ingame_if_loaded}, - raycast::update_raycasts, queue::apply_queued_blocks + raycast::update_raycasts, + queue::apply_queued_blocks }; use player::spawn_player; use prefabs::load_prefabs; @@ -55,7 +57,7 @@ use rendering::{ RenderTarget, BackgroundColor, clear_background, - primitives::init_simple_box_buffers, + primitives::init_primitives, selection_box::render_selection_box, world::draw_world, world::draw_current_chunk_border, @@ -64,18 +66,21 @@ use block_placement::block_placement_system; use delta_time::{DeltaTime, init_delta_time}; use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow}; -use state::{GameState, is_ingame, is_ingame_or_loading, is_loading}; +use state::{is_ingame, is_ingame_or_loading, is_loading}; use init::initialize_from_args; +use gui::{render_gui, init_gui, gui_testing}; fn startup() -> Workload { ( load_settings, load_prefabs, - init_simple_box_buffers, + init_primitives, insert_lock_state, initialize_from_args, lock_cursor_now, init_input, + init_gui, + gui_testing, init_game_world, spawn_player, insert_control_flow_unique, @@ -110,7 +115,8 @@ fn render() -> Workload { draw_world, draw_current_chunk_border, render_selection_box, - ).into_sequential_workload().run_if(is_ingame) + ).into_sequential_workload().run_if(is_ingame), + render_gui, ).into_sequential_workload() } fn after_frame_end() -> Workload { diff --git a/kubi/src/prefabs.rs b/kubi/src/prefabs.rs index 4529bce..6d1aa76 100644 --- a/kubi/src/prefabs.rs +++ b/kubi/src/prefabs.rs @@ -62,7 +62,10 @@ pub struct ChunkShaderPrefab(pub Program); pub struct SelBoxShaderPrefab(pub Program); #[derive(Unique)] -pub struct BasicColoredShaderPrefab(pub Program); +pub struct ColoredShaderPrefab(pub Program); + +#[derive(Unique)] +pub struct ProgressbarShaderPrefab(pub Program); pub fn load_prefabs( storages: AllStoragesView, @@ -94,7 +97,7 @@ pub fn load_prefabs( &renderer.display ) )); - storages.add_unique_non_send_sync(BasicColoredShaderPrefab( + storages.add_unique_non_send_sync(ColoredShaderPrefab( include_shader_prefab!( "colored", "../shaders/colored.vert", @@ -102,4 +105,12 @@ pub fn load_prefabs( &renderer.display ) )); + storages.add_unique_non_send_sync(ProgressbarShaderPrefab( + include_shader_prefab!( + "gui/progressbar", + "../shaders/gui/progressbar.vert", + "../shaders/gui/progressbar.frag", + &renderer.display + ) + )); } diff --git a/kubi/src/rendering/primitives.rs b/kubi/src/rendering/primitives.rs index ce05f83..6861b3e 100644 --- a/kubi/src/rendering/primitives.rs +++ b/kubi/src/rendering/primitives.rs @@ -1,39 +1,11 @@ -use glium::{implement_vertex, VertexBuffer, IndexBuffer, index::PrimitiveType}; -use shipyard::{NonSendSync, UniqueView, AllStoragesView, Unique}; -use super::Renderer; +use shipyard::{Workload, IntoWorkload}; +use glium::implement_vertex; -pub const CUBE_VERTICES: &[f32] = &[ - // front - 0.0, 0.0, 1.0, - 1.0, 0.0, 1.0, - 1.0, 1.0, 1.0, - 0.0, 1.0, 1.0, - // back - 0.0, 0.0, 0.0, - 1.0, 0.0, 0.0, - 1.0, 1.0, 0.0, - 0.0, 1.0, 0.0 -]; -pub const CUBE_INDICES: &[u16] = &[ - // front - 0, 1, 2, - 2, 3, 0, - // right - 1, 5, 6, - 6, 2, 1, - // back - 7, 6, 5, - 5, 4, 7, - // left - 4, 0, 3, - 3, 7, 4, - // bottom - 4, 5, 1, - 1, 0, 4, - // top - 3, 2, 6, - 6, 7, 3 -]; +pub mod cube; +pub mod rect; + +use cube::init_cube_primitive; +use rect::init_rect_primitive; #[derive(Clone, Copy, Default)] pub struct PositionOnlyVertex { @@ -41,40 +13,15 @@ pub struct PositionOnlyVertex { } implement_vertex!(PositionOnlyVertex, position); -const fn box_vertices() -> [PositionOnlyVertex; CUBE_VERTICES.len() / 3] { - let mut arr = [PositionOnlyVertex { position: [0., 0., 0.] }; CUBE_VERTICES.len() / 3]; - let mut ptr = 0; - loop { - arr[ptr] = PositionOnlyVertex { - position: [ - CUBE_VERTICES[ptr * 3], - CUBE_VERTICES[(ptr * 3) + 1], - CUBE_VERTICES[(ptr * 3) + 2] - ] - }; - ptr += 1; - if ptr >= CUBE_VERTICES.len() / 3 { - return arr - } - } +#[derive(Clone, Copy, Default)] +pub struct PositionOnlyVertex2d { + pub position: [f32; 2], } -const BOX_VERTICES: &[PositionOnlyVertex] = &box_vertices(); +implement_vertex!(PositionOnlyVertex2d, position); -#[derive(Unique)] -pub struct SimpleBoxBuffers(pub VertexBuffer, pub IndexBuffer); - -pub fn init_simple_box_buffers( - storages: AllStoragesView, - display: NonSendSync> -) { - let vert = VertexBuffer::new( - &display.display, - BOX_VERTICES - ).unwrap(); - let index = IndexBuffer::new( - &display.display, - PrimitiveType::TrianglesList, - CUBE_INDICES - ).unwrap(); - storages.add_unique_non_send_sync(SimpleBoxBuffers(vert, index)); +pub fn init_primitives() -> Workload { + ( + init_cube_primitive, + init_rect_primitive, + ).into_workload() } diff --git a/kubi/src/rendering/primitives/cube.rs b/kubi/src/rendering/primitives/cube.rs new file mode 100644 index 0000000..cee8f02 --- /dev/null +++ b/kubi/src/rendering/primitives/cube.rs @@ -0,0 +1,56 @@ +use shipyard::{AllStoragesView, NonSendSync, UniqueView, Unique}; +use glium::{VertexBuffer, IndexBuffer, index::PrimitiveType}; +use crate::rendering::Renderer; +use super::PositionOnlyVertex; + +#[derive(Unique)] +pub struct CubePrimitive(pub VertexBuffer, pub IndexBuffer); + +const CUBE_VERTICES: &[PositionOnlyVertex] = &[ + // front + PositionOnlyVertex { position: [0.0, 0.0, 1.0] }, + PositionOnlyVertex { position: [1.0, 0.0, 1.0] }, + PositionOnlyVertex { position: [1.0, 1.0, 1.0] }, + PositionOnlyVertex { position: [0.0, 1.0, 1.0] }, + // back + PositionOnlyVertex { position: [0.0, 0.0, 0.0] }, + PositionOnlyVertex { position: [1.0, 0.0, 0.0] }, + PositionOnlyVertex { position: [1.0, 1.0, 0.0] }, + PositionOnlyVertex { position: [0.0, 1.0, 0.0] }, +]; +const CUBE_INDICES: &[u16] = &[ + // front + 0, 1, 2, + 2, 3, 0, + // right + 1, 5, 6, + 6, 2, 1, + // back + 7, 6, 5, + 5, 4, 7, + // left + 4, 0, 3, + 3, 7, 4, + // bottom + 4, 5, 1, + 1, 0, 4, + // top + 3, 2, 6, + 6, 7, 3 +]; + +pub(super) fn init_cube_primitive( + storages: AllStoragesView, + display: NonSendSync> +) { + let vert = VertexBuffer::new( + &display.display, + CUBE_VERTICES + ).unwrap(); + let index = IndexBuffer::new( + &display.display, + PrimitiveType::TrianglesList, + CUBE_INDICES + ).unwrap(); + storages.add_unique_non_send_sync(CubePrimitive(vert, index)); +} diff --git a/kubi/src/rendering/primitives/rect.rs b/kubi/src/rendering/primitives/rect.rs new file mode 100644 index 0000000..0215d14 --- /dev/null +++ b/kubi/src/rendering/primitives/rect.rs @@ -0,0 +1,31 @@ +use shipyard::{Unique, AllStoragesView, NonSendSync, UniqueView}; +use glium::{VertexBuffer, IndexBuffer, index::PrimitiveType}; +use crate::rendering::Renderer; +use super::PositionOnlyVertex2d; + +#[derive(Unique)] +pub struct RectPrimitive(pub VertexBuffer, pub IndexBuffer); + +const RECT_VERTEX: &[PositionOnlyVertex2d] = &[ + PositionOnlyVertex2d { position: [0., 0.] }, + PositionOnlyVertex2d { position: [1., 0.] }, + PositionOnlyVertex2d { position: [0., 1.] }, + PositionOnlyVertex2d { position: [1., 1.] }, +]; +const RECT_INDEX: &[u16] = &[0, 1, 2, 1, 3, 2]; + +pub(super) fn init_rect_primitive( + storages: AllStoragesView, + display: NonSendSync> +) { + let vert = VertexBuffer::new( + &display.display, + RECT_VERTEX + ).unwrap(); + let index = IndexBuffer::new( + &display.display, + PrimitiveType::TrianglesList, + RECT_INDEX + ).unwrap(); + storages.add_unique_non_send_sync(RectPrimitive(vert, index)); +} diff --git a/kubi/src/rendering/selection_box.rs b/kubi/src/rendering/selection_box.rs index b04f75c..1c8cc5a 100644 --- a/kubi/src/rendering/selection_box.rs +++ b/kubi/src/rendering/selection_box.rs @@ -12,7 +12,7 @@ use crate::{ }; use super::{ RenderTarget, - primitives::SimpleBoxBuffers, + primitives::cube::CubePrimitive, }; pub fn render_selection_box( @@ -20,7 +20,7 @@ pub fn render_selection_box( camera: View, mut target: NonSendSync>, program: NonSendSync>, - buffers: NonSendSync>, + buffers: NonSendSync>, ) { let camera = camera.iter().next().unwrap(); let Some(lookat) = lookat.iter().next() else { return }; diff --git a/kubi/src/rendering/world.rs b/kubi/src/rendering/world.rs index f4770ec..a42136b 100644 --- a/kubi/src/rendering/world.rs +++ b/kubi/src/rendering/world.rs @@ -24,7 +24,7 @@ use crate::{ prefabs::{ ChunkShaderPrefab, BlockTexturesPrefab, - BasicColoredShaderPrefab, + ColoredShaderPrefab, }, world::{ ChunkStorage, @@ -32,7 +32,7 @@ use crate::{ chunk::CHUNK_SIZE, }, settings::GameSettings, }; -use super::{RenderTarget, primitives::SimpleBoxBuffers}; +use super::{RenderTarget, primitives::cube::CubePrimitive}; #[derive(Clone, Copy)] pub struct ChunkVertex { @@ -114,8 +114,8 @@ pub fn draw_current_chunk_border( mut target: NonSendSync>, player: View, transforms: View, - buffers: NonSendSync>, - program: NonSendSync>, + buffers: NonSendSync>, + program: NonSendSync>, camera: View, settings: UniqueView, ) { diff --git a/kubi/src/transform.rs b/kubi/src/transform.rs index 5087b6c..643603e 100644 --- a/kubi/src/transform.rs +++ b/kubi/src/transform.rs @@ -1,5 +1,5 @@ use shipyard::Component; -use glam::Mat4; +use glam::{Mat4, Vec2}; #[derive(Component, Clone, Copy, Debug, Default)] #[track(All)]