gui and progressbars

This commit is contained in:
griffi-gh 2023-02-09 03:31:36 +01:00
parent 9f2e47df8c
commit 8ed0765c9f
17 changed files with 284 additions and 98 deletions

View file

@ -2,6 +2,10 @@
members = ["kubi", "kubi-server", "kubi-shared", "kubi-udp"] members = ["kubi", "kubi-server", "kubi-shared", "kubi-udp"]
resolver = "2" resolver = "2"
[profile.release-with-debug]
inherits = "release"
debug = true
[profile.dev] [profile.dev]
opt-level = 1 opt-level = 1

View file

@ -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);
}

View file

@ -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);
}

View file

@ -1,7 +1,7 @@
use shipyard::{UniqueViewMut, UniqueView, View, IntoIter, ViewMut, EntitiesViewMut}; use shipyard::{UniqueViewMut, UniqueView, View, IntoIter, ViewMut, EntitiesViewMut};
use crate::{ use crate::{
player::MainPlayer, player::MainPlayer,
world::{raycast::LookingAtBlock, ChunkStorage, block::Block, queue::{BlockUpdateQueue, BlockUpdateEvent}}, world::{raycast::LookingAtBlock, block::Block, queue::{BlockUpdateQueue, BlockUpdateEvent}},
input::{Inputs, PrevInputs}, input::{Inputs, PrevInputs},
events::{EventComponent, player_actions::PlayerActionEvent}, events::{EventComponent, player_actions::PlayerActionEvent},
}; };

12
kubi/src/color.rs Normal file
View file

@ -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)
}

View file

@ -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 text_widget;
pub mod progressbar; 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(),
));
}

View file

@ -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<UniqueViewMut<RenderTarget>>,
rect: NonSendSync<UniqueView<RectPrimitive>>,
program: NonSendSync<UniqueView<ProgressbarShaderPrefab>>,
view: UniqueView<GuiViewScale>,
components: View<GuiComponent>,
transforms: View<GuiTransform>,
progressbars: View<ProgressbarComponent>,
primary: View<PrimaryColor>,
secondary: View<SecondaryColor>,
) {
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();
}
}

View file

@ -0,0 +1 @@
//TODO text widget

View file

@ -34,11 +34,13 @@ pub(crate) mod state;
pub(crate) mod gui; pub(crate) mod gui;
pub(crate) mod networking; pub(crate) mod networking;
pub(crate) mod init; pub(crate) mod init;
pub(crate) mod color;
use world::{ use world::{
init_game_world, init_game_world,
loading::{update_loaded_world_around_player, switch_to_ingame_if_loaded}, 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 player::spawn_player;
use prefabs::load_prefabs; use prefabs::load_prefabs;
@ -55,7 +57,7 @@ use rendering::{
RenderTarget, RenderTarget,
BackgroundColor, BackgroundColor,
clear_background, clear_background,
primitives::init_simple_box_buffers, primitives::init_primitives,
selection_box::render_selection_box, selection_box::render_selection_box,
world::draw_world, world::draw_world,
world::draw_current_chunk_border, world::draw_current_chunk_border,
@ -64,18 +66,21 @@ use block_placement::block_placement_system;
use delta_time::{DeltaTime, init_delta_time}; use delta_time::{DeltaTime, init_delta_time};
use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; 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 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 init::initialize_from_args;
use gui::{render_gui, init_gui, gui_testing};
fn startup() -> Workload { fn startup() -> Workload {
( (
load_settings, load_settings,
load_prefabs, load_prefabs,
init_simple_box_buffers, init_primitives,
insert_lock_state, insert_lock_state,
initialize_from_args, initialize_from_args,
lock_cursor_now, lock_cursor_now,
init_input, init_input,
init_gui,
gui_testing,
init_game_world, init_game_world,
spawn_player, spawn_player,
insert_control_flow_unique, insert_control_flow_unique,
@ -110,7 +115,8 @@ fn render() -> Workload {
draw_world, draw_world,
draw_current_chunk_border, draw_current_chunk_border,
render_selection_box, render_selection_box,
).into_sequential_workload().run_if(is_ingame) ).into_sequential_workload().run_if(is_ingame),
render_gui,
).into_sequential_workload() ).into_sequential_workload()
} }
fn after_frame_end() -> Workload { fn after_frame_end() -> Workload {

View file

@ -62,7 +62,10 @@ pub struct ChunkShaderPrefab(pub Program);
pub struct SelBoxShaderPrefab(pub Program); pub struct SelBoxShaderPrefab(pub Program);
#[derive(Unique)] #[derive(Unique)]
pub struct BasicColoredShaderPrefab(pub Program); pub struct ColoredShaderPrefab(pub Program);
#[derive(Unique)]
pub struct ProgressbarShaderPrefab(pub Program);
pub fn load_prefabs( pub fn load_prefabs(
storages: AllStoragesView, storages: AllStoragesView,
@ -94,7 +97,7 @@ pub fn load_prefabs(
&renderer.display &renderer.display
) )
)); ));
storages.add_unique_non_send_sync(BasicColoredShaderPrefab( storages.add_unique_non_send_sync(ColoredShaderPrefab(
include_shader_prefab!( include_shader_prefab!(
"colored", "colored",
"../shaders/colored.vert", "../shaders/colored.vert",
@ -102,4 +105,12 @@ pub fn load_prefabs(
&renderer.display &renderer.display
) )
)); ));
storages.add_unique_non_send_sync(ProgressbarShaderPrefab(
include_shader_prefab!(
"gui/progressbar",
"../shaders/gui/progressbar.vert",
"../shaders/gui/progressbar.frag",
&renderer.display
)
));
} }

View file

@ -1,39 +1,11 @@
use glium::{implement_vertex, VertexBuffer, IndexBuffer, index::PrimitiveType}; use shipyard::{Workload, IntoWorkload};
use shipyard::{NonSendSync, UniqueView, AllStoragesView, Unique}; use glium::implement_vertex;
use super::Renderer;
pub const CUBE_VERTICES: &[f32] = &[ pub mod cube;
// front pub mod rect;
0.0, 0.0, 1.0,
1.0, 0.0, 1.0, use cube::init_cube_primitive;
1.0, 1.0, 1.0, use rect::init_rect_primitive;
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
];
#[derive(Clone, Copy, Default)] #[derive(Clone, Copy, Default)]
pub struct PositionOnlyVertex { pub struct PositionOnlyVertex {
@ -41,40 +13,15 @@ pub struct PositionOnlyVertex {
} }
implement_vertex!(PositionOnlyVertex, position); implement_vertex!(PositionOnlyVertex, position);
const fn box_vertices() -> [PositionOnlyVertex; CUBE_VERTICES.len() / 3] { #[derive(Clone, Copy, Default)]
let mut arr = [PositionOnlyVertex { position: [0., 0., 0.] }; CUBE_VERTICES.len() / 3]; pub struct PositionOnlyVertex2d {
let mut ptr = 0; pub position: [f32; 2],
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
}
}
} }
const BOX_VERTICES: &[PositionOnlyVertex] = &box_vertices(); implement_vertex!(PositionOnlyVertex2d, position);
#[derive(Unique)] pub fn init_primitives() -> Workload {
pub struct SimpleBoxBuffers(pub VertexBuffer<PositionOnlyVertex>, pub IndexBuffer<u16>); (
init_cube_primitive,
pub fn init_simple_box_buffers( init_rect_primitive,
storages: AllStoragesView, ).into_workload()
display: NonSendSync<UniqueView<Renderer>>
) {
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));
} }

View file

@ -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<PositionOnlyVertex>, pub IndexBuffer<u16>);
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<UniqueView<Renderer>>
) {
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));
}

View file

@ -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<PositionOnlyVertex2d>, pub IndexBuffer<u16>);
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<UniqueView<Renderer>>
) {
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));
}

View file

@ -12,7 +12,7 @@ use crate::{
}; };
use super::{ use super::{
RenderTarget, RenderTarget,
primitives::SimpleBoxBuffers, primitives::cube::CubePrimitive,
}; };
pub fn render_selection_box( pub fn render_selection_box(
@ -20,7 +20,7 @@ pub fn render_selection_box(
camera: View<Camera>, camera: View<Camera>,
mut target: NonSendSync<UniqueViewMut<RenderTarget>>, mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
program: NonSendSync<UniqueView<SelBoxShaderPrefab>>, program: NonSendSync<UniqueView<SelBoxShaderPrefab>>,
buffers: NonSendSync<UniqueView<SimpleBoxBuffers>>, buffers: NonSendSync<UniqueView<CubePrimitive>>,
) { ) {
let camera = camera.iter().next().unwrap(); let camera = camera.iter().next().unwrap();
let Some(lookat) = lookat.iter().next() else { return }; let Some(lookat) = lookat.iter().next() else { return };

View file

@ -24,7 +24,7 @@ use crate::{
prefabs::{ prefabs::{
ChunkShaderPrefab, ChunkShaderPrefab,
BlockTexturesPrefab, BlockTexturesPrefab,
BasicColoredShaderPrefab, ColoredShaderPrefab,
}, },
world::{ world::{
ChunkStorage, ChunkStorage,
@ -32,7 +32,7 @@ use crate::{
chunk::CHUNK_SIZE, chunk::CHUNK_SIZE,
}, settings::GameSettings, }, settings::GameSettings,
}; };
use super::{RenderTarget, primitives::SimpleBoxBuffers}; use super::{RenderTarget, primitives::cube::CubePrimitive};
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct ChunkVertex { pub struct ChunkVertex {
@ -114,8 +114,8 @@ pub fn draw_current_chunk_border(
mut target: NonSendSync<UniqueViewMut<RenderTarget>>, mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
player: View<MainPlayer>, player: View<MainPlayer>,
transforms: View<Transform>, transforms: View<Transform>,
buffers: NonSendSync<UniqueView<SimpleBoxBuffers>>, buffers: NonSendSync<UniqueView<CubePrimitive>>,
program: NonSendSync<UniqueView<BasicColoredShaderPrefab>>, program: NonSendSync<UniqueView<ColoredShaderPrefab>>,
camera: View<Camera>, camera: View<Camera>,
settings: UniqueView<GameSettings>, settings: UniqueView<GameSettings>,
) { ) {

View file

@ -1,5 +1,5 @@
use shipyard::Component; use shipyard::Component;
use glam::Mat4; use glam::{Mat4, Vec2};
#[derive(Component, Clone, Copy, Debug, Default)] #[derive(Component, Clone, Copy, Debug, Default)]
#[track(All)] #[track(All)]