integrate ui

This commit is contained in:
griffi-gh 2023-11-22 14:23:48 +01:00
parent 467e61cb70
commit 09effab7c3
8 changed files with 110 additions and 31 deletions

View file

@ -2,7 +2,8 @@
precision highp float; precision highp float;
in vec2 position; in vec2 position;
uniform vec2 resolution;
void main() { void main() {
gl_Position = vec4(position, 0., 1.); gl_Position = vec4(vec2(1., -1.) * (position / resolution), 0., 1.);
} }

View file

@ -9,8 +9,8 @@ use glium::{
use crate::draw::{UiDrawPlan, UiVertex}; use crate::draw::{UiDrawPlan, UiVertex};
const VERTEX_SHADER: &str = include_str!("../../shaders/fragment.frag"); const VERTEX_SHADER: &str = include_str!("../../shaders/vertex.vert");
const FRAGMENT_SHADER: &str = include_str!("../../shaders/vertex.vert"); const FRAGMENT_SHADER: &str = include_str!("../../shaders/fragment.frag");
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
struct Vertex { struct Vertex {
@ -50,10 +50,38 @@ impl GliumUiRenderer {
} }
} }
pub fn draw(&mut self, frame: &mut glium::Frame, resolution: Vec2, plan: &UiDrawPlan) { fn ensure_buffer_size(&mut self, need_vtx: usize, need_idx: usize) {
self.vertex_buffer.write(&plan.vertices.iter().copied().map(Vertex::from).collect::<Vec<_>>()); let current_vtx_size = self.vertex_buffer.get_size();
self.index_buffer.write(&plan.indices); let current_idx_size = self.index_buffer.get_size();
if current_vtx_size >= need_vtx && current_idx_size >= need_idx {
return
}
let new_vtx_size = (need_vtx + 1).next_power_of_two();
let new_idx_size = (need_idx + 1).next_power_of_two();
log::debug!("resizing buffers: vtx {} -> {}, idx {} -> {}", current_vtx_size, new_vtx_size, current_idx_size, new_idx_size);
if current_vtx_size != new_vtx_size {
self.vertex_buffer = VertexBuffer::empty_persistent(self.vertex_buffer.get_context(), new_vtx_size).unwrap();
}
if current_idx_size != new_idx_size {
self.index_buffer = IndexBuffer::empty_persistent(self.index_buffer.get_context(), PrimitiveType::TrianglesList, new_idx_size).unwrap();
}
}
fn write_buffer_data(&mut self, vtx: &[Vertex], idx: &[u32]) {
self.ensure_buffer_size(vtx.len(), idx.len());
self.vertex_buffer.invalidate();
self.vertex_buffer.slice_mut(0..vtx.len()).unwrap().write(vtx);
self.index_buffer.invalidate();
self.index_buffer.slice_mut(0..idx.len()).unwrap().write(idx);
}
pub fn update(&mut self, plan: &UiDrawPlan) {
let data_vtx = &plan.vertices.iter().copied().map(Vertex::from).collect::<Vec<_>>();
let data_idx = &plan.indices;
self.write_buffer_data(data_vtx, data_idx);
}
pub fn draw(&self, frame: &mut glium::Frame, resolution: Vec2) {
let params = DrawParameters { let params = DrawParameters {
blend: Blend::alpha_blending(), blend: Blend::alpha_blending(),
..Default::default() ..Default::default()

View file

@ -0,0 +1,45 @@
use kubi_ui::{KubiUi, backend::glium::GliumUiRenderer};
use shipyard::{AllStoragesView, Unique, UniqueView, NonSendSync, UniqueViewMut};
use crate::rendering::{Renderer, RenderTarget, WindowSize};
#[derive(Unique)]
pub struct UiState {
pub ui: KubiUi,
pub renderer: GliumUiRenderer,
}
pub fn kubi_ui_init(
storages: AllStoragesView
) {
let renderer = storages.borrow::<NonSendSync<UniqueView<Renderer>>>().unwrap();
storages.add_unique_non_send_sync(UiState {
ui: KubiUi::new(),
renderer: GliumUiRenderer::new(&renderer.display)
});
}
pub fn kubi_ui_begin(
mut ui: NonSendSync<UniqueViewMut<UiState>>
) {
ui.ui.begin();
}
pub fn kubi_ui_end(
mut ui: NonSendSync<UniqueViewMut<UiState>>
) {
let ui: &mut UiState = &mut ui;
let UiState { ui, renderer } = ui;
ui.end();
let (upload_needed, plan) = ui.draw_plan();
if upload_needed {
renderer.update(plan);
}
}
pub fn kubi_ui_draw(
ui: NonSendSync<UniqueView<UiState>>,
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
size: UniqueView<WindowSize>
) {
ui.renderer.draw(&mut target.0, size.0.as_vec2());
}

View file

@ -9,29 +9,29 @@ use progressbar::render_progressbars;
//TODO compute gui scale on window resize //TODO compute gui scale on window resize
#[derive(Unique, Clone, Copy, Debug, Default)] #[derive(Unique, Clone, Copy, Debug, Default)]
pub struct GuiView(pub Mat4); pub struct LegacyGuiView(pub Mat4);
#[derive(Component, Clone, Copy, Debug, Default)] #[derive(Component, Clone, Copy, Debug, Default)]
pub struct GuiComponent; pub struct LegacyGuiComponent;
#[derive(Component, Clone, Copy, Debug)] #[derive(Component, Clone, Copy, Debug)]
pub struct PrimaryColor(pub Vec4); pub struct LegacyPrimaryColor(pub Vec4);
impl Default for PrimaryColor { impl Default for LegacyPrimaryColor {
fn default() -> Self { fn default() -> Self {
Self(color_hex(0x156cddff)) Self(color_hex(0x156cddff))
} }
} }
#[derive(Component, Clone, Copy, Debug)] #[derive(Component, Clone, Copy, Debug)]
pub struct SecondaryColor(pub Vec4); pub struct LegacySecondaryColor(pub Vec4);
impl Default for SecondaryColor { impl Default for LegacySecondaryColor {
fn default() -> Self { fn default() -> Self {
Self(color_hex(0xc9d5e4ff)) Self(color_hex(0xc9d5e4ff))
} }
} }
fn update_gui_view( fn update_legacy_gui_view(
mut view: UniqueViewMut<GuiView>, mut view: UniqueViewMut<LegacyGuiView>,
resize: View<WindowResizedEvent>, resize: View<WindowResizedEvent>,
) { ) {
let Some(&size) = resize.iter().next() else { let Some(&size) = resize.iter().next() else {
@ -41,19 +41,19 @@ fn update_gui_view(
view.0 = Mat4::orthographic_rh_gl(0.0, w as f32, h as f32, 0.0, -1.0, 1.0); view.0 = Mat4::orthographic_rh_gl(0.0, w as f32, h as f32, 0.0, -1.0, 1.0);
} }
pub fn init_gui( pub fn legacy_ui_init(
storages: AllStoragesView storages: AllStoragesView
) { ) {
storages.add_unique(GuiView::default()); storages.add_unique(LegacyGuiView::default());
} }
pub fn update_gui() -> Workload { pub fn legacy_ui_update() -> Workload {
( (
update_gui_view update_legacy_gui_view
).into_sequential_workload() ).into_sequential_workload()
} }
pub fn render_gui() -> Workload { pub fn legacy_ui_render() -> Workload {
( (
render_progressbars render_progressbars
).into_sequential_workload() ).into_sequential_workload()

View file

@ -8,7 +8,7 @@ use crate::{
}, },
transform::Transform2d, transform::Transform2d,
}; };
use super::{GuiComponent, PrimaryColor, SecondaryColor, GuiView}; use super::{LegacyGuiComponent, LegacyPrimaryColor, LegacySecondaryColor, LegacyGuiView};
#[derive(Component, Debug, Clone, Copy, Default)] #[derive(Component, Debug, Clone, Copy, Default)]
pub struct ProgressbarComponent { pub struct ProgressbarComponent {
@ -19,12 +19,12 @@ pub fn render_progressbars(
mut target: NonSendSync<UniqueViewMut<RenderTarget>>, mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
rect: NonSendSync<UniqueView<RectPrimitive>>, rect: NonSendSync<UniqueView<RectPrimitive>>,
program: NonSendSync<UniqueView<ProgressbarShaderPrefab>>, program: NonSendSync<UniqueView<ProgressbarShaderPrefab>>,
view: UniqueView<GuiView>, view: UniqueView<LegacyGuiView>,
components: View<GuiComponent>, components: View<LegacyGuiComponent>,
transforms: View<Transform2d, track::All>, transforms: View<Transform2d, track::All>,
progressbars: View<ProgressbarComponent>, progressbars: View<ProgressbarComponent>,
primary: View<PrimaryColor>, primary: View<LegacyPrimaryColor>,
secondary: View<SecondaryColor>, secondary: View<LegacySecondaryColor>,
) { ) {
for (eid, (_, transform, progress)) in (&components, &transforms, &progressbars).iter().with_id() { for (eid, (_, transform, progress)) in (&components, &transforms, &progressbars).iter().with_id() {
let primary_color = primary.get(eid).copied().unwrap_or_default(); let primary_color = primary.get(eid).copied().unwrap_or_default();

View file

@ -30,6 +30,7 @@ pub(crate) mod cursor_lock;
pub(crate) mod control_flow; pub(crate) mod control_flow;
pub(crate) mod state; pub(crate) mod state;
pub(crate) mod legacy_gui; pub(crate) mod legacy_gui;
pub(crate) mod guiv2_integration;
pub(crate) mod networking; pub(crate) mod networking;
pub(crate) mod init; pub(crate) mod init;
pub(crate) mod color; pub(crate) mod color;
@ -43,7 +44,7 @@ use world::{
loading::update_loaded_world_around_player, loading::update_loaded_world_around_player,
raycast::update_raycasts, raycast::update_raycasts,
queue::apply_queued_blocks, queue::apply_queued_blocks,
tasks::{ChunkTaskManager}, tasks::ChunkTaskManager,
}; };
use player::{spawn_player, MainPlayer}; use player::{spawn_player, MainPlayer};
use prefabs::load_prefabs; use prefabs::load_prefabs;
@ -76,7 +77,8 @@ use control_flow::{exit_on_esc, insert_control_flow_unique, RequestExit};
use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state, is_connecting}; use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state, is_connecting};
use networking::{update_networking, update_networking_late, is_multiplayer, disconnect_on_exit, is_singleplayer}; use networking::{update_networking, update_networking_late, is_multiplayer, disconnect_on_exit, is_singleplayer};
use init::initialize_from_args; use init::initialize_from_args;
use legacy_gui::{render_gui, init_gui, update_gui}; use legacy_gui::{legacy_ui_render, legacy_ui_init, legacy_ui_update};
use guiv2_integration::{kubi_ui_init, kubi_ui_begin, kubi_ui_end, kubi_ui_draw};
use loading_screen::update_loading_screen; use loading_screen::update_loading_screen;
use connecting_screen::switch_to_loading_if_connected; use connecting_screen::switch_to_loading_if_connected;
use fixed_timestamp::init_fixed_timestamp_storage; use fixed_timestamp::init_fixed_timestamp_storage;
@ -94,6 +96,7 @@ fn startup() -> Workload {
init_fixed_timestamp_storage, init_fixed_timestamp_storage,
initial_resize_event, initial_resize_event,
init_window_size, init_window_size,
kubi_ui_init,
load_prefabs, load_prefabs,
init_primitives, init_primitives,
insert_lock_state, insert_lock_state,
@ -101,7 +104,7 @@ fn startup() -> Workload {
initialize_from_args, initialize_from_args,
lock_cursor_now, lock_cursor_now,
init_input, init_input,
init_gui, legacy_ui_init,
insert_control_flow_unique, insert_control_flow_unique,
init_delta_time, init_delta_time,
).into_sequential_workload() ).into_sequential_workload()
@ -112,6 +115,7 @@ fn update() -> Workload {
update_window_size, update_window_size,
update_cursor_lock_state, update_cursor_lock_state,
process_inputs, process_inputs,
kubi_ui_begin,
( (
init_game_world.run_if_missing_unique::<ChunkTaskManager>(), init_game_world.run_if_missing_unique::<ChunkTaskManager>(),
( (
@ -137,7 +141,8 @@ fn update() -> Workload {
).into_sequential_workload().run_if(is_ingame), ).into_sequential_workload().run_if(is_ingame),
update_networking_late.run_if(is_multiplayer), update_networking_late.run_if(is_multiplayer),
compute_cameras, compute_cameras,
update_gui, legacy_ui_update,
kubi_ui_end,
update_state, update_state,
exit_on_esc, exit_on_esc,
disconnect_on_exit.run_if(is_multiplayer), disconnect_on_exit.run_if(is_multiplayer),
@ -153,7 +158,7 @@ fn render() -> Workload {
render_selection_box, render_selection_box,
render_entities, render_entities,
).into_sequential_workload().run_if(is_ingame), ).into_sequential_workload().run_if(is_ingame),
render_gui, legacy_ui_render,
).into_sequential_workload() ).into_sequential_workload()
} }

View file

@ -6,7 +6,7 @@ use crate::{
state::{GameState, NextState, is_changing_state}, state::{GameState, NextState, is_changing_state},
transform::Transform2d, transform::Transform2d,
legacy_gui::{ legacy_gui::{
GuiComponent, LegacyGuiComponent,
progressbar::ProgressbarComponent progressbar::ProgressbarComponent
}, },
rendering::{WindowSize, if_resized}, rendering::{WindowSize, if_resized},
@ -21,7 +21,7 @@ fn spawn_loading_screen(
) { ) {
let size = *storages.borrow::<UniqueView<WindowSize>>().unwrap(); let size = *storages.borrow::<UniqueView<WindowSize>>().unwrap();
let entity = storages.add_entity(( let entity = storages.add_entity((
GuiComponent, LegacyGuiComponent,
Transform2d(Mat3::from_scale_angle_translation( Transform2d(Mat3::from_scale_angle_translation(
vec2(size.0.x as f32, 16.), vec2(size.0.x as f32, 16.),
0., 0.,