mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-22 06:48:43 -06:00
Compare commits
8 commits
447a06e9de
...
ac497b0651
Author | SHA1 | Date | |
---|---|---|---|
griffi-gh | ac497b0651 | ||
griffi-gh | 567fd1d6aa | ||
griffi-gh | d9d3f78066 | ||
griffi-gh | 22c13eeaea | ||
griffi-gh | 09effab7c3 | ||
griffi-gh | 467e61cb70 | ||
griffi-gh | d75a5fa3cb | ||
griffi-gh | a3857d0586 |
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1033,6 +1033,7 @@ dependencies = [
|
||||||
"glam",
|
"glam",
|
||||||
"glium",
|
"glium",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
|
"log",
|
||||||
"nohash-hasher",
|
"nohash-hasher",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ pub fn init() {
|
||||||
level_style.set_color(match record.level() {
|
level_style.set_color(match record.level() {
|
||||||
Level::Error => Color::Red,
|
Level::Error => Color::Red,
|
||||||
Level::Warn => Color::Yellow,
|
Level::Warn => Color::Yellow,
|
||||||
|
Level::Debug | Level::Trace => Color::Cyan,
|
||||||
_ => Color::Blue
|
_ => Color::Blue
|
||||||
}).set_bold(true);
|
}).set_bold(true);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ hashbrown = "0.14"
|
||||||
nohash-hasher = "0.2"
|
nohash-hasher = "0.2"
|
||||||
glam = { version = "0.24", features = ["approx"] }
|
glam = { version = "0.24", features = ["approx"] }
|
||||||
glium = { git = "https://github.com/glium/glium", rev = "968fc92378caf", optional = true }
|
glium = { git = "https://github.com/glium/glium", rev = "968fc92378caf", optional = true }
|
||||||
|
log = "0.4"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["backend_glium", "builtin_elements"]
|
default = ["backend_glium", "builtin_elements"]
|
||||||
|
|
10
kubi-ui/shaders/fragment.frag
Normal file
10
kubi-ui/shaders/fragment.frag
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#version 300 es
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
out vec4 out_color;
|
||||||
|
uniform vec4 color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
if (color.w <= 0.) discard;
|
||||||
|
out_color = color;
|
||||||
|
}
|
9
kubi-ui/shaders/vertex.vert
Normal file
9
kubi-ui/shaders/vertex.vert
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#version 300 es
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
in vec2 position;
|
||||||
|
uniform vec2 resolution;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(vec2(1., -1.) * (position / resolution), 0., 1.);
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
use glam::Vec2;
|
||||||
|
use glium::{
|
||||||
|
Surface, DrawParameters, Blend,
|
||||||
|
Program, VertexBuffer, IndexBuffer,
|
||||||
|
backend::Facade,
|
||||||
|
index::PrimitiveType,
|
||||||
|
implement_vertex, uniform,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::draw::{UiDrawPlan, UiVertex};
|
||||||
|
|
||||||
|
const VERTEX_SHADER: &str = include_str!("../../shaders/vertex.vert");
|
||||||
|
const FRAGMENT_SHADER: &str = include_str!("../../shaders/fragment.frag");
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
struct Vertex {
|
||||||
|
position: [f32; 2],
|
||||||
|
color: [f32; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<UiVertex> for Vertex {
|
||||||
|
fn from(v: UiVertex) -> Self {
|
||||||
|
Self {
|
||||||
|
position: v.position.to_array(),
|
||||||
|
color: v.color.to_array(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
implement_vertex!(Vertex, position, color);
|
||||||
|
|
||||||
|
pub struct GliumUiRenderer {
|
||||||
|
pub program: glium::Program,
|
||||||
|
pub vertex_buffer: glium::VertexBuffer<Vertex>,
|
||||||
|
pub index_buffer: glium::IndexBuffer<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GliumUiRenderer {
|
||||||
|
pub fn new<F: Facade>(facade: &F) -> Self {
|
||||||
|
log::info!("init glium backend for ui");
|
||||||
|
log::debug!("init program");
|
||||||
|
let program = Program::from_source(facade, VERTEX_SHADER, FRAGMENT_SHADER, None).unwrap();
|
||||||
|
log::debug!("init buffers");
|
||||||
|
let vertex_buffer = VertexBuffer::empty_persistent(facade, 1024).unwrap();
|
||||||
|
let index_buffer = IndexBuffer::empty_persistent(facade, PrimitiveType::TrianglesList, 1024).unwrap();
|
||||||
|
Self {
|
||||||
|
program,
|
||||||
|
vertex_buffer,
|
||||||
|
index_buffer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ensure_buffer_size(&mut self, need_vtx: usize, need_idx: usize) {
|
||||||
|
let current_vtx_size = self.vertex_buffer.get_size();
|
||||||
|
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]) {
|
||||||
|
log::info!("uploading {} vertices and {} indices", vtx.len(), idx.len());
|
||||||
|
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 {
|
||||||
|
blend: Blend::alpha_blending(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
frame.draw(
|
||||||
|
&self.vertex_buffer,
|
||||||
|
&self.index_buffer,
|
||||||
|
&self.program,
|
||||||
|
&uniform! {
|
||||||
|
resolution: resolution.to_array(),
|
||||||
|
},
|
||||||
|
¶ms,
|
||||||
|
).unwrap();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
use glam::{Vec2, vec2, Vec4};
|
use std::num::NonZeroU16;
|
||||||
|
use glam::{Vec2, Vec4};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub enum UiDrawCall {
|
pub enum UiDrawCommand {
|
||||||
///Filled, colored rectangle
|
///Filled, colored rectangle
|
||||||
Rectangle {
|
Rectangle {
|
||||||
///Position in pixels
|
///Position in pixels
|
||||||
|
@ -13,10 +14,60 @@ pub enum UiDrawCall {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UiDrawCalls {
|
#[derive(Default)]
|
||||||
pub calls: Vec<UiDrawCall>,
|
pub struct UiDrawCommands {
|
||||||
|
pub commands: Vec<UiDrawCommand>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl UiDrawCommands {
|
||||||
|
// pub fn compare(&self, other: &Self) -> bool {
|
||||||
|
// // if self.commands.len() != other.commands.len() { return false }
|
||||||
|
// // self.commands.iter().zip(other.commands.iter()).all(|(a, b)| a == b)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
pub struct UiVertex {
|
||||||
|
pub position: Vec2,
|
||||||
|
pub color: Vec4,
|
||||||
|
//pub texture: Option<NonZeroU16>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
pub struct UiDrawPlan {
|
pub struct UiDrawPlan {
|
||||||
|
pub vertices: Vec<UiVertex>,
|
||||||
|
pub indices: Vec<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UiDrawPlan {
|
||||||
|
pub fn build(calls: &UiDrawCommands) -> Self {
|
||||||
|
let mut plan = Self::default();
|
||||||
|
for call in &calls.commands {
|
||||||
|
match call {
|
||||||
|
UiDrawCommand::Rectangle { position, size, color } => {
|
||||||
|
let idx = plan.vertices.len() as u32;
|
||||||
|
plan.indices.extend([idx, idx + 1, idx + 2, idx, idx + 2, idx + 3]);
|
||||||
|
plan.vertices.extend([
|
||||||
|
UiVertex {
|
||||||
|
position: *position,
|
||||||
|
color: *color,
|
||||||
|
},
|
||||||
|
UiVertex {
|
||||||
|
position: *position + Vec2::new(size.x, 0.0),
|
||||||
|
color: *color,
|
||||||
|
},
|
||||||
|
UiVertex {
|
||||||
|
position: *position + *size,
|
||||||
|
color: *color,
|
||||||
|
},
|
||||||
|
UiVertex {
|
||||||
|
position: *position + Vec2::new(0.0, size.y),
|
||||||
|
color: *color,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
plan
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use crate::{
|
use crate::{
|
||||||
LayoutInfo,
|
LayoutInfo,
|
||||||
draw::UiDrawCall,
|
draw::UiDrawCommand,
|
||||||
measure::Response,
|
measure::Response,
|
||||||
state::StateRepo
|
state::StateRepo
|
||||||
};
|
};
|
||||||
|
@ -17,5 +17,5 @@ pub trait UiElement {
|
||||||
fn is_stateless(&self) -> bool { self.state_id().is_none() }
|
fn is_stateless(&self) -> bool { self.state_id().is_none() }
|
||||||
fn init_state(&self) -> Option<Box<dyn Any>> { None }
|
fn init_state(&self) -> Option<Box<dyn Any>> { None }
|
||||||
fn measure(&self, state: &StateRepo, layout: &LayoutInfo) -> Response;
|
fn measure(&self, state: &StateRepo, layout: &LayoutInfo) -> Response;
|
||||||
fn draw(&self, measure: &Response, state: &mut StateRepo, layout: &LayoutInfo, draw: &mut Vec<UiDrawCall>);
|
fn process(&self, measure: &Response, state: &mut StateRepo, layout: &LayoutInfo, draw: &mut Vec<UiDrawCommand>);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use glam::{Vec2, Vec4};
|
use glam::{Vec2, Vec4};
|
||||||
use crate::{UiDirection, LayoutInfo, draw::UiDrawCall, measure::{IsMeasurable, Response}, state::StateRepo, UiSize};
|
use crate::{UiDirection, LayoutInfo, draw::UiDrawCommand, measure::{IsMeasurable, Response}, state::StateRepo, UiSize};
|
||||||
use super::UiElement;
|
use super::UiElement;
|
||||||
|
|
||||||
#[derive(Default, Clone, Copy, Debug)]
|
#[derive(Default, Clone, Copy, Debug)]
|
||||||
|
@ -73,9 +73,9 @@ impl UiElement for Container {
|
||||||
Response { desired_size: size }
|
Response { desired_size: size }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, measure: &Response, state: &mut StateRepo, layout: &LayoutInfo, draw: &mut Vec<UiDrawCall>) {
|
fn process(&self, measure: &Response, state: &mut StateRepo, layout: &LayoutInfo, draw: &mut Vec<UiDrawCommand>) {
|
||||||
if let Some(color) = self.background {
|
if let Some(color) = self.background {
|
||||||
draw.push(UiDrawCall::Rectangle {
|
draw.push(UiDrawCommand::Rectangle {
|
||||||
position: layout.position,
|
position: layout.position,
|
||||||
size: measure.desired_size,
|
size: measure.desired_size,
|
||||||
color
|
color
|
||||||
|
|
|
@ -1,17 +1,28 @@
|
||||||
use glam::{vec2, Vec4};
|
use glam::{vec2, Vec4, vec4};
|
||||||
use crate::{
|
use crate::{
|
||||||
UiSize, LayoutInfo,
|
UiSize, LayoutInfo,
|
||||||
draw::UiDrawCall,
|
draw::UiDrawCommand,
|
||||||
measure::Response,
|
measure::Response,
|
||||||
state::StateRepo
|
state::StateRepo
|
||||||
};
|
};
|
||||||
use super::UiElement;
|
use super::UiElement;
|
||||||
|
|
||||||
struct ProgressBar {
|
pub struct ProgressBar {
|
||||||
size: (UiSize, UiSize),
|
pub size: (UiSize, UiSize),
|
||||||
value: f32,
|
pub value: f32,
|
||||||
color_foreground: Vec4,
|
pub color_foreground: Vec4,
|
||||||
color_background: Vec4,
|
pub color_background: Vec4,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ProgressBar {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
size: (UiSize::Auto, UiSize::Auto),
|
||||||
|
value: 0.,
|
||||||
|
color_foreground: vec4(0.0, 0.0, 1.0, 1.0),
|
||||||
|
color_background: vec4(0.0, 0.0, 0.0, 1.0),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const BAR_HEIGHT: f32 = 20.0;
|
const BAR_HEIGHT: f32 = 20.0;
|
||||||
|
@ -36,14 +47,14 @@ impl UiElement for ProgressBar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, measure: &Response, state: &mut StateRepo, layout: &LayoutInfo, draw: &mut Vec<UiDrawCall>) {
|
fn process(&self, measure: &Response, state: &mut StateRepo, layout: &LayoutInfo, draw: &mut Vec<UiDrawCommand>) {
|
||||||
draw.push(UiDrawCall::Rectangle {
|
draw.push(UiDrawCommand::Rectangle {
|
||||||
position: layout.position,
|
position: layout.position,
|
||||||
size: measure.desired_size,
|
size: measure.desired_size,
|
||||||
color: self.color_background
|
color: self.color_background
|
||||||
});
|
});
|
||||||
|
|
||||||
draw.push(UiDrawCall::Rectangle {
|
draw.push(UiDrawCommand::Rectangle {
|
||||||
position: layout.position,
|
position: layout.position,
|
||||||
size: measure.desired_size * vec2(self.value, 1.0),
|
size: measure.desired_size * vec2(self.value, 1.0),
|
||||||
color: self.color_foreground
|
color: self.color_foreground
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use glam::vec2;
|
use glam::vec2;
|
||||||
use crate::{state::StateRepo, LayoutInfo, measure::Response, draw::UiDrawCall, UiDirection};
|
use crate::{state::StateRepo, LayoutInfo, measure::Response, draw::UiDrawCommand, UiDirection};
|
||||||
use super::UiElement;
|
use super::UiElement;
|
||||||
|
|
||||||
pub struct Spacer(f32);
|
pub struct Spacer(f32);
|
||||||
|
@ -14,5 +14,5 @@ impl UiElement for Spacer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, _measure: &Response, _state: &mut StateRepo, _layout: &LayoutInfo, _draw: &mut Vec<UiDrawCall>) {}
|
fn process(&self, _measure: &Response, _state: &mut StateRepo, _layout: &LayoutInfo, _draw: &mut Vec<UiDrawCommand>) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,19 @@ pub mod backend;
|
||||||
pub mod measure;
|
pub mod measure;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
|
|
||||||
|
use element::UiElement;
|
||||||
use state::StateRepo;
|
use state::StateRepo;
|
||||||
|
use event::UiEvent;
|
||||||
|
use draw::{UiDrawCommands, UiDrawPlan};
|
||||||
|
|
||||||
pub struct KubiUi {
|
pub struct KubiUi {
|
||||||
mouse_position: Vec2,
|
mouse_position: Vec2,
|
||||||
stateful_state: StateRepo,
|
stateful_state: StateRepo,
|
||||||
event_queue: VecDeque<event::UiEvent>,
|
event_queue: VecDeque<UiEvent>,
|
||||||
|
prev_draw_commands: UiDrawCommands,
|
||||||
|
draw_commands: UiDrawCommands,
|
||||||
|
draw_plan: UiDrawPlan,
|
||||||
|
draw_plan_modified: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KubiUi {
|
impl KubiUi {
|
||||||
|
@ -22,8 +29,31 @@ impl KubiUi {
|
||||||
mouse_position: Vec2::ZERO,
|
mouse_position: Vec2::ZERO,
|
||||||
stateful_state: StateRepo::default(),
|
stateful_state: StateRepo::default(),
|
||||||
event_queue: VecDeque::new(),
|
event_queue: VecDeque::new(),
|
||||||
|
// root_elements: Vec::new(),
|
||||||
|
prev_draw_commands: UiDrawCommands::default(),
|
||||||
|
draw_commands: UiDrawCommands::default(),
|
||||||
|
draw_plan: UiDrawPlan::default(),
|
||||||
|
draw_plan_modified: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn begin(&mut self) {
|
||||||
|
std::mem::swap(&mut self.prev_draw_commands, &mut self.draw_commands);
|
||||||
|
self.draw_plan_modified = false;
|
||||||
|
self.draw_commands.commands.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn end(&mut self) {
|
||||||
|
if self.draw_commands.commands == self.prev_draw_commands.commands {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.draw_plan = UiDrawPlan::build(&self.draw_commands);
|
||||||
|
self.draw_plan_modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_plan(&self) -> (bool, &UiDrawPlan) {
|
||||||
|
(self.draw_plan_modified, &self.draw_plan)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for KubiUi {
|
impl Default for KubiUi {
|
||||||
|
|
45
kubi/src/guiv2_integration.rs
Normal file
45
kubi/src/guiv2_integration.rs
Normal 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());
|
||||||
|
}
|
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.,
|
||||||
|
|
|
@ -92,5 +92,8 @@ pub fn load_prefabs(
|
||||||
&renderer.display
|
&renderer.display
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
log::info!("releasing shader compiler");
|
||||||
|
|
||||||
renderer.display.release_shader_compiler();
|
renderer.display.release_shader_compiler();
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,8 +234,8 @@ fn process_completed_tasks(
|
||||||
}
|
}
|
||||||
|
|
||||||
//apply the mesh
|
//apply the mesh
|
||||||
let vertex_buffer = VertexBuffer::new(&renderer.display, &vertices).unwrap();
|
let vertex_buffer = VertexBuffer::immutable(&renderer.display, &vertices).unwrap();
|
||||||
let index_buffer = IndexBuffer::new(&renderer.display, PrimitiveType::TrianglesList, &indexes).unwrap();
|
let index_buffer = IndexBuffer::immutable(&renderer.display, PrimitiveType::TrianglesList, &indexes).unwrap();
|
||||||
let mesh = ChunkMesh {
|
let mesh = ChunkMesh {
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
index_buffer,
|
index_buffer,
|
||||||
|
|
Loading…
Reference in a new issue