mirror of
https://github.com/griffi-gh/hUI.git
synced 2025-04-07 16:36:27 -05:00
mostly fix stuff
This commit is contained in:
parent
b49f0c2dba
commit
e8851ee356
hui-examples
hui-glium
hui-painter/src
hui-wgpu
hui
|
@ -7,7 +7,7 @@ publish = false
|
|||
|
||||
[dev-dependencies]
|
||||
hui = { path = "../hui" }
|
||||
# hui-painter = { path = "../hui-painter" }
|
||||
hui-painter = { path = "../hui-painter" }
|
||||
hui-glium = { path = "../hui-glium" }
|
||||
hui-winit = { path = "../hui-winit" }
|
||||
kubi-logging = { git = "https://github.com/griffi-gh/kubi", rev = "1e051c47b64c967305e4bbbd464ef5da2cc56bbb" }
|
||||
|
|
|
@ -65,9 +65,9 @@ pub fn ui<T>(
|
|||
let size = UVec2::from(display.get_framebuffer_dimensions()).as_vec2();
|
||||
draw(&mut hui, size, &mut result);
|
||||
|
||||
hui.end();
|
||||
hui.end_frame();
|
||||
|
||||
backend.update(&hui);
|
||||
backend.update(&hui.backend_data());
|
||||
backend.draw(&mut frame, size);
|
||||
|
||||
frame.finish().unwrap();
|
||||
|
|
|
@ -135,7 +135,7 @@ fn main() {
|
|||
..Default::default()
|
||||
}, resolution);
|
||||
|
||||
hui.end();
|
||||
hui.end_frame();
|
||||
|
||||
backend.update(&hui);
|
||||
backend.draw(&mut frame, resolution);
|
||||
|
|
|
@ -106,7 +106,7 @@ fn main() {
|
|||
..Default::default()
|
||||
}, resolution);
|
||||
|
||||
hui.end();
|
||||
hui.end_frame();
|
||||
|
||||
backend.update(&hui);
|
||||
backend.draw(&mut frame, resolution);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use hui::{
|
||||
draw::TextureFormat,
|
||||
element::{
|
||||
br::Break,
|
||||
container::Container,
|
||||
|
@ -12,6 +11,7 @@ use hui::{
|
|||
layout::{Alignment, Direction},
|
||||
size,
|
||||
};
|
||||
use hui_painter::texture::SourceTextureFormat;
|
||||
|
||||
#[derive(Signal)]
|
||||
enum CounterSignal {
|
||||
|
@ -27,7 +27,7 @@ const IMAGE_DATA: &[u8] = include_bytes!("../assets/icons/visual-studio-code-ico
|
|||
ui_main!(
|
||||
"hUI: Internal input test",
|
||||
init: |ui| {
|
||||
let image = ui.add_image(TextureFormat::Rgba, IMAGE_DATA, 32);
|
||||
let image = ui.add_image(SourceTextureFormat::RGBA8, IMAGE_DATA, 32);
|
||||
(0, image)
|
||||
},
|
||||
run: |ui, size, &mut (ref mut counter, image)| {
|
||||
|
@ -41,11 +41,11 @@ ui_main!(
|
|||
.with_wrap(true)
|
||||
.with_children(|ui| {
|
||||
Text::new(format!("Number of images: {counter}"))
|
||||
.with_text_size(32)
|
||||
.with_text_size(32.)
|
||||
.add_child(ui);
|
||||
Break.add_child(ui);
|
||||
Text::new("Absolute tracking slider:")
|
||||
.with_text_size(16)
|
||||
.with_text_size(16.)
|
||||
.add_child(ui);
|
||||
Break.add_child(ui);
|
||||
Slider::new(*counter as f32 / 100.)
|
||||
|
@ -56,7 +56,7 @@ ui_main!(
|
|||
.add_child(ui);
|
||||
Break.add_child(ui);
|
||||
Text::new("Relative tracking slider (Experimental):")
|
||||
.with_text_size(16)
|
||||
.with_text_size(16.)
|
||||
.add_child(ui);
|
||||
Break.add_child(ui);
|
||||
Slider::new(*counter as f32 / 100.)
|
||||
|
|
|
@ -16,7 +16,8 @@ include = [
|
|||
]
|
||||
|
||||
[dependencies]
|
||||
hui = { version = "=0.1.0-alpha.6", path = "../hui", default-features = false }
|
||||
# hui = { version = "=0.1.0-alpha.6", path = "../hui", default-features = false }
|
||||
hui-painter = { version = "=0.1.0-alpha.6", path = "../hui-painter", default-features = false }
|
||||
glium = { version = "0.36", default-features = false }
|
||||
glam = "0.30"
|
||||
log = "0.4"
|
||||
|
|
|
@ -21,7 +21,7 @@ use glium::{
|
|||
implement_vertex,
|
||||
uniform,
|
||||
};
|
||||
use hui::UiInstance;
|
||||
use hui_painter::{backend::BackendData, paint::buffer::Vertex, presentation::PresentatationBackendData, texture::TextureAtlasBackendData};
|
||||
|
||||
const VERTEX_SHADER_GLES3: &str = include_str!("../shaders/vertex.es.vert");
|
||||
const FRAGMENT_SHADER_GLES3: &str = include_str!("../shaders/fragment.es.frag");
|
||||
|
@ -31,14 +31,14 @@ const FRAGMENT_SHADER_150: &str = include_str!("../shaders/fragment.150.frag");
|
|||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
struct Vertex {
|
||||
struct GlVertex {
|
||||
position: [f32; 2],
|
||||
color: [f32; 4],
|
||||
uv: [f32; 2],
|
||||
}
|
||||
|
||||
impl From<UiVertex> for Vertex {
|
||||
fn from(v: UiVertex) -> Self {
|
||||
impl From<Vertex> for GlVertex {
|
||||
fn from(v: Vertex) -> Self {
|
||||
Self {
|
||||
position: v.position.to_array(),
|
||||
color: v.color.to_array(),
|
||||
|
@ -47,10 +47,10 @@ impl From<UiVertex> for Vertex {
|
|||
}
|
||||
}
|
||||
|
||||
implement_vertex!(Vertex, position, color, uv);
|
||||
implement_vertex!(GlVertex, position, color, uv);
|
||||
|
||||
struct BufferPair {
|
||||
pub vertex_buffer: glium::VertexBuffer<Vertex>,
|
||||
pub vertex_buffer: glium::VertexBuffer<GlVertex>,
|
||||
pub index_buffer: glium::IndexBuffer<u32>,
|
||||
pub vertex_count: usize,
|
||||
pub index_count: usize,
|
||||
|
@ -67,7 +67,7 @@ impl BufferPair {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new_with_data<F: Facade>(facade: &F, vtx: &[Vertex], idx: &[u32]) -> Self {
|
||||
pub fn new_with_data<F: Facade>(facade: &F, vtx: &[GlVertex], idx: &[u32]) -> Self {
|
||||
log::debug!("init ui buffers (data)...");
|
||||
Self {
|
||||
vertex_buffer: VertexBuffer::dynamic(facade, vtx).unwrap(),
|
||||
|
@ -78,7 +78,7 @@ impl BufferPair {
|
|||
}
|
||||
|
||||
pub fn ensure_buffer_size(&mut self, need_vtx: usize, need_idx: usize) {
|
||||
let current_vtx_size = self.vertex_buffer.get_size() / std::mem::size_of::<Vertex>();
|
||||
let current_vtx_size = self.vertex_buffer.get_size() / std::mem::size_of::<GlVertex>();
|
||||
let current_idx_size = self.index_buffer.get_size() / std::mem::size_of::<u32>();
|
||||
//log::debug!("current vtx size: {}, current idx size: {}", current_vtx_size, current_idx_size);
|
||||
if current_vtx_size >= need_vtx && current_idx_size >= need_idx {
|
||||
|
@ -102,7 +102,7 @@ impl BufferPair {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn write_data(&mut self, vtx: &[Vertex], idx: &[u32]) {
|
||||
pub fn write_data(&mut self, vtx: &[GlVertex], idx: &[u32]) {
|
||||
//log::trace!("uploading {} vertices and {} indices", vtx.len(), idx.len());
|
||||
|
||||
self.vertex_count = vtx.len();
|
||||
|
@ -129,7 +129,9 @@ pub struct GliumUiRenderer {
|
|||
context: Rc<Context>,
|
||||
program: glium::Program,
|
||||
ui_texture: Option<Texture2d>,
|
||||
ui_texture_version: u64,
|
||||
buffer_pair: Option<BufferPair>,
|
||||
buffer_hash: u64,
|
||||
}
|
||||
|
||||
impl GliumUiRenderer {
|
||||
|
@ -142,22 +144,25 @@ impl GliumUiRenderer {
|
|||
},
|
||||
context: Rc::clone(facade.get_context()),
|
||||
ui_texture: None,
|
||||
ui_texture_version: 0,
|
||||
buffer_pair: None,
|
||||
buffer_hash: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn update_buffers(&mut self, call: &UiDrawCall) {
|
||||
log::trace!("updating ui buffers (tris: {})", call.indices.len() / 3);
|
||||
let data_vtx = &call.vertices.iter().copied().map(Vertex::from).collect::<Vec<_>>()[..];
|
||||
let data_idx = &call.indices[..];
|
||||
fn update_buffers(&mut self, data: &PresentatationBackendData) {
|
||||
log::trace!("updating ui buffers (tris: {})", data.buffer.indices.len() / 3);
|
||||
let data_vtx = &data.buffer.vertices.iter().copied().map(GlVertex::from).collect::<Vec<_>>()[..];
|
||||
let data_idx = &data.buffer.indices[..];
|
||||
if let Some(buffer) = &mut self.buffer_pair {
|
||||
buffer.write_data(data_vtx, data_idx);
|
||||
} else if !call.indices.is_empty() {
|
||||
} else if !data.buffer.indices.is_empty() {
|
||||
self.buffer_pair = Some(BufferPair::new_with_data(&self.context, data_vtx, data_idx));
|
||||
}
|
||||
self.buffer_hash = data.hash;
|
||||
}
|
||||
|
||||
fn update_texture_atlas(&mut self, atlas: &TextureAtlasMeta) {
|
||||
fn update_texture_atlas(&mut self, atlas: &TextureAtlasBackendData) {
|
||||
log::trace!("updating ui atlas texture");
|
||||
self.ui_texture = Some(Texture2d::new(
|
||||
&self.context,
|
||||
|
@ -166,14 +171,15 @@ impl GliumUiRenderer {
|
|||
(atlas.size.x, atlas.size.y)
|
||||
)
|
||||
).unwrap());
|
||||
self.ui_texture_version = atlas.version;
|
||||
}
|
||||
|
||||
pub fn update(&mut self, instance: &UiInstance) {
|
||||
if self.ui_texture.is_none() || instance.backend_atlas().modified {
|
||||
self.update_texture_atlas(&instance.backend_atlas());
|
||||
pub fn update(&mut self, data: &BackendData) {
|
||||
if self.ui_texture_version != data.atlas.version {
|
||||
self.update_texture_atlas(&data.atlas);
|
||||
}
|
||||
if self.buffer_pair.is_none() || instance.backend_paint_buffer().0 {
|
||||
self.update_buffers(instance.backend_paint_buffer().1);
|
||||
if self.buffer_hash != data.presentation.hash {
|
||||
self.update_buffers(&data.presentation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,83 +1,9 @@
|
|||
use crate::{
|
||||
paint::{buffer::PaintBuffer, command::{PaintCommand, PaintRoot}},
|
||||
presentation::{Presentatation, PresentatationBackendData},
|
||||
texture::TextureAtlasBackendData,
|
||||
PainterInstance,
|
||||
};
|
||||
|
||||
pub struct Presentatation {
|
||||
current_buffer: PaintBuffer,
|
||||
cur_hash: Option<u64>,
|
||||
prev_hash: Option<u64>,
|
||||
version_counter: u64,
|
||||
}
|
||||
|
||||
impl Presentatation {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
current_buffer: PaintBuffer::new(),
|
||||
cur_hash: None,
|
||||
prev_hash: None,
|
||||
version_counter: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// If the paint command has changed since the last draw call, draw it and return true.\
|
||||
/// Otherwise, returns false.
|
||||
pub fn draw(&mut self, painter: &mut PainterInstance, cmd: &impl PaintRoot) -> bool {
|
||||
self.prev_hash = self.cur_hash;
|
||||
self.cur_hash = Some(cmd.cache_hash());
|
||||
|
||||
if self.prev_hash == self.cur_hash {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.current_buffer.clear();
|
||||
cmd.paint_root(painter, &mut self.current_buffer);
|
||||
|
||||
self.version_counter = self.version_counter.wrapping_add(1);
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Get the current paint buffer
|
||||
pub fn buffer(&self) -> &PaintBuffer {
|
||||
&self.current_buffer
|
||||
}
|
||||
|
||||
/// Get the complete backend data for the current presentation
|
||||
///
|
||||
/// It contains the current paint buffer and the hash of the presentation\
|
||||
/// Unlike the `TextureAtlasBackendData`, the version is non-incremental
|
||||
pub fn backend_data(&self) -> PresentatationBackendData {
|
||||
PresentatationBackendData {
|
||||
buffer: &self.current_buffer,
|
||||
version: self.version_counter,
|
||||
hash: self.cur_hash.unwrap_or(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Presentatation {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// Backend data for the Presentation
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct PresentatationBackendData<'a> {
|
||||
/// The current paint buffer
|
||||
pub buffer: &'a PaintBuffer,
|
||||
|
||||
/// The version of the presentation
|
||||
///
|
||||
/// This is incremented every time the buffer hash changes
|
||||
pub version: u64,
|
||||
|
||||
/// Unique hash of current paint buffer commands
|
||||
pub hash: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct BackendData<'a> {
|
||||
pub presentation: PresentatationBackendData<'a>,
|
||||
|
@ -93,22 +19,4 @@ impl PainterInstance {
|
|||
}
|
||||
}
|
||||
|
||||
// pub trait HasPainter {
|
||||
// fn painter(&self) -> &PainterInstance;
|
||||
// fn painter_mut(&self) -> &mut PainterInstance;
|
||||
// }
|
||||
|
||||
// pub trait PresentFrontend: HasPainter {
|
||||
// fn commands(&self) -> &dyn PaintCommand;
|
||||
|
||||
// fn present(&self, backend: &mut dyn PresentBackend) {
|
||||
// backend.presentation().draw(
|
||||
// self.painter_mut(),
|
||||
// self.commands(),
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
pub trait RenderBackend {
|
||||
fn presentation(&self) -> &mut Presentatation;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ pub mod texture;
|
|||
pub mod text;
|
||||
pub mod util;
|
||||
pub mod backend;
|
||||
pub mod presentation;
|
||||
|
||||
use text::FontManager;
|
||||
use texture::TextureAtlas;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use glam::{Vec2, Vec4};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct Vertex {
|
||||
pub position: Vec2, //Vec3,
|
||||
pub uv: Vec2,
|
||||
|
|
83
hui-painter/src/presentation.rs
Normal file
83
hui-painter/src/presentation.rs
Normal file
|
@ -0,0 +1,83 @@
|
|||
use crate::{
|
||||
PainterInstance,
|
||||
paint::{
|
||||
buffer::PaintBuffer,
|
||||
command::PaintRoot,
|
||||
},
|
||||
};
|
||||
|
||||
pub struct Presentatation {
|
||||
current_buffer: PaintBuffer,
|
||||
cur_hash: Option<u64>,
|
||||
prev_hash: Option<u64>,
|
||||
version_counter: u64,
|
||||
}
|
||||
|
||||
impl Presentatation {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
current_buffer: PaintBuffer::new(),
|
||||
cur_hash: None,
|
||||
prev_hash: None,
|
||||
version_counter: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// If the paint command has changed since the last draw call, draw it and return true.\
|
||||
/// Otherwise, returns false.
|
||||
pub fn draw(&mut self, painter: &mut PainterInstance, cmd: &impl PaintRoot) -> bool {
|
||||
self.prev_hash = self.cur_hash;
|
||||
self.cur_hash = Some(cmd.cache_hash());
|
||||
|
||||
if self.prev_hash == self.cur_hash {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.current_buffer.clear();
|
||||
cmd.paint_root(painter, &mut self.current_buffer);
|
||||
|
||||
self.version_counter = self.version_counter.wrapping_add(1);
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Get the current paint buffer
|
||||
pub fn buffer(&self) -> &PaintBuffer {
|
||||
&self.current_buffer
|
||||
}
|
||||
|
||||
/// Get the complete backend data for the current presentation
|
||||
///
|
||||
/// It contains the current paint buffer and the hash of the presentation\
|
||||
/// Unlike the `TextureAtlasBackendData`, the version is non-incremental
|
||||
pub fn backend_data(&self) -> PresentatationBackendData {
|
||||
PresentatationBackendData {
|
||||
buffer: &self.current_buffer,
|
||||
version: self.version_counter,
|
||||
hash: self.cur_hash.unwrap_or(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Presentatation {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Backend data for the Presentation
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct PresentatationBackendData<'a> {
|
||||
/// The current paint buffer
|
||||
pub buffer: &'a PaintBuffer,
|
||||
|
||||
/// The version of the presentation
|
||||
///
|
||||
/// This is incremented every time the buffer hash changes
|
||||
pub version: u64,
|
||||
|
||||
/// Unique hash of current paint buffer commands
|
||||
pub hash: u64,
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@ include = [
|
|||
]
|
||||
|
||||
[dependencies]
|
||||
hui = { version = "=0.1.0-alpha.6", path = "../hui", default-features = false }
|
||||
hui-painter = { version = "=0.1.0-alpha.6", path = "../hui-painter", default-features = false }
|
||||
wgpu = { version = "24", default-features = false, features = ["wgsl"]}
|
||||
bytemuck = "1.15"
|
||||
log = "0.4"
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
use glam::{vec2, Vec2};
|
||||
use hui::{draw::{TextureAtlasMeta, UiDrawCall, UiVertex}, UiInstance};
|
||||
use hui_painter::{
|
||||
backend::BackendData,
|
||||
paint::buffer::Vertex,
|
||||
presentation::PresentatationBackendData,
|
||||
texture::TextureAtlasBackendData
|
||||
};
|
||||
|
||||
const DEFAULT_BUFFER_SIZE: u64 = 1024;
|
||||
const DEFAULT_TEXTURE_SIZE: u32 = 512;
|
||||
|
@ -27,8 +32,8 @@ impl WgpuVertex {
|
|||
};
|
||||
}
|
||||
|
||||
impl From<UiVertex> for WgpuVertex {
|
||||
fn from(v: UiVertex) -> Self {
|
||||
impl From<Vertex> for WgpuVertex {
|
||||
fn from(v: Vertex) -> Self {
|
||||
Self {
|
||||
position: v.position.to_array(),
|
||||
uv: v.uv.to_array(),
|
||||
|
@ -38,7 +43,9 @@ impl From<UiVertex> for WgpuVertex {
|
|||
}
|
||||
|
||||
pub struct WgpuUiRenderer {
|
||||
pub modified: bool,
|
||||
// pub modified: bool,
|
||||
pub last_buf_hash: u64,
|
||||
pub last_img_version: u64,
|
||||
pub vertex_buffer: wgpu::Buffer,
|
||||
pub index_buffer: wgpu::Buffer,
|
||||
pub vertex_count: usize,
|
||||
|
@ -184,7 +191,8 @@ impl WgpuUiRenderer {
|
|||
});
|
||||
|
||||
Self {
|
||||
modified: true,
|
||||
last_buf_hash: 0,
|
||||
last_img_version: 0,
|
||||
vertex_buffer,
|
||||
index_buffer,
|
||||
vertex_count: 0,
|
||||
|
@ -198,8 +206,8 @@ impl WgpuUiRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
fn update_buffers(&mut self, call: &UiDrawCall, queue: &wgpu::Queue, device: &wgpu::Device, resolution: Vec2) {
|
||||
let data_vtx = call.vertices.iter()
|
||||
fn update_buffers(&mut self, present_data: &PresentatationBackendData, queue: &wgpu::Queue, device: &wgpu::Device, resolution: Vec2) {
|
||||
let data_vtx = present_data.buffer.vertices.iter()
|
||||
.copied()
|
||||
.map(|x| {
|
||||
let mut v = x;
|
||||
|
@ -208,13 +216,13 @@ impl WgpuUiRenderer {
|
|||
})
|
||||
.map(WgpuVertex::from)
|
||||
.collect::<Vec<_>>();
|
||||
let data_idx = &call.indices[..];
|
||||
let data_idx = &present_data.buffer.indices[..];
|
||||
|
||||
let data_vtx_view = bytemuck::cast_slice(&data_vtx);
|
||||
let data_idx_view = bytemuck::cast_slice(data_idx);
|
||||
|
||||
self.vertex_count = call.vertices.len();
|
||||
self.index_count = call.indices.len();
|
||||
self.vertex_count = present_data.buffer.vertices.len();
|
||||
self.index_count = present_data.buffer.indices.len();
|
||||
|
||||
if data_vtx.is_empty() || data_idx.is_empty() {
|
||||
return
|
||||
|
@ -240,11 +248,13 @@ impl WgpuUiRenderer {
|
|||
|
||||
queue.write_buffer(&self.vertex_buffer, 0, data_vtx_view);
|
||||
queue.write_buffer(&self.index_buffer, 0, data_idx_view);
|
||||
|
||||
self.last_buf_hash = present_data.hash;
|
||||
}
|
||||
|
||||
fn update_texture(&mut self, meta: TextureAtlasMeta, queue: &wgpu::Queue, device: &wgpu::Device) {
|
||||
fn update_texture(&mut self, atlas: &TextureAtlasBackendData, queue: &wgpu::Queue, device: &wgpu::Device) {
|
||||
//TODO URGENCY:HIGH resize texture if needed
|
||||
if meta.data.len() as u32 > (self.texture.size().width * self.texture.size().height * 4) {
|
||||
if atlas.data.len() as u32 > (self.texture.size().width * self.texture.size().height * 4) {
|
||||
self.texture.destroy();
|
||||
// unimplemented!("texture resize not implemented");
|
||||
self.texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||
|
@ -263,44 +273,41 @@ impl WgpuUiRenderer {
|
|||
});
|
||||
}
|
||||
queue.write_texture(
|
||||
wgpu::ImageCopyTexture {
|
||||
wgpu::TexelCopyTextureInfo {
|
||||
texture: &self.texture,
|
||||
mip_level: 0,
|
||||
origin: wgpu::Origin3d::ZERO,
|
||||
aspect: wgpu::TextureAspect::All,
|
||||
},
|
||||
meta.data,
|
||||
wgpu::ImageDataLayout {
|
||||
atlas.data,
|
||||
wgpu::TexelCopyBufferLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: Some(meta.size.x * 4),
|
||||
rows_per_image: Some(meta.size.y),
|
||||
bytes_per_row: Some(atlas.size.x * 4),
|
||||
rows_per_image: Some(atlas.size.y),
|
||||
},
|
||||
wgpu::Extent3d {
|
||||
width: meta.size.x,
|
||||
height: meta.size.y,
|
||||
width: atlas.size.x,
|
||||
height: atlas.size.y,
|
||||
depth_or_array_layers: 1,
|
||||
}
|
||||
);
|
||||
|
||||
self.last_img_version = atlas.version;
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
&mut self,
|
||||
instance: &UiInstance,
|
||||
data: &BackendData,
|
||||
queue: &wgpu::Queue,
|
||||
device: &wgpu::Device,
|
||||
resolution: Vec2,
|
||||
) {
|
||||
let (modified, call) = instance.backend_paint_buffer();
|
||||
if self.modified || modified {
|
||||
self.update_buffers(call, queue, device, resolution);
|
||||
if data.presentation.hash != self.last_buf_hash {
|
||||
self.update_buffers(&data.presentation, queue, device, resolution);
|
||||
}
|
||||
|
||||
let meta = instance.backend_atlas();
|
||||
if self.modified || meta.modified {
|
||||
self.update_texture(meta, queue, device);
|
||||
if data.atlas.version != self.last_img_version {
|
||||
self.update_texture(&data.atlas, queue, device);
|
||||
}
|
||||
|
||||
self.modified = false;
|
||||
}
|
||||
|
||||
pub fn draw(
|
||||
|
|
|
@ -33,7 +33,7 @@ image = { version = "0.25", default-features = false, optional = true }
|
|||
rustc-hash = "2.0"
|
||||
|
||||
[features]
|
||||
default = ["el_all", "image", "builtin_font", "derive"]
|
||||
default = ["el_all", "derive"]
|
||||
|
||||
## Enable derive macros
|
||||
derive = ["dep:hui-derive"]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use hui_painter::{
|
||||
backend::{BackendData, Presentatation}, paint::{buffer::PaintBuffer, command::{PaintCommand, PaintList, PaintRoot}}, text::FontHandle, texture::{SourceTextureFormat, TextureAtlasBackendData, TextureHandle}, PainterInstance
|
||||
backend::BackendData, paint::command::{PaintCommand, PaintList}, presentation::Presentatation, text::FontHandle, texture::{SourceTextureFormat, TextureHandle}, PainterInstance
|
||||
};
|
||||
use crate::{
|
||||
element::{MeasureContext, ProcessContext, UiElement},
|
||||
|
@ -17,13 +17,18 @@ use crate::{
|
|||
/// In most cases, you should only have one instance of this struct, but multiple instances are allowed\
|
||||
/// (Please note that it's possible to render multiple UI "roots" using a single instance)
|
||||
pub struct UiInstance {
|
||||
// TODO Do not own Presentation/Painter
|
||||
painter: PainterInstance,
|
||||
presentation: Presentatation,
|
||||
paint_commands: PaintList,
|
||||
stateful_state: StateRepo,
|
||||
events: EventQueue,
|
||||
input: UiInputState,
|
||||
signal: SignalStore,
|
||||
font_stack: FontStack,
|
||||
|
||||
/// Set to true if present has been called since the last begin_frame
|
||||
frame_presented: bool,
|
||||
}
|
||||
|
||||
impl UiInstance {
|
||||
|
@ -33,12 +38,14 @@ impl UiInstance {
|
|||
pub fn new() -> Self {
|
||||
UiInstance {
|
||||
painter: PainterInstance::new(),
|
||||
presentation: Presentatation::new(),
|
||||
paint_commands: PaintList::default(),
|
||||
font_stack: FontStack::new(),
|
||||
stateful_state: StateRepo::new(),
|
||||
events: EventQueue::new(),
|
||||
input: UiInputState::new(),
|
||||
signal: SignalStore::new(),
|
||||
frame_presented: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,12 +172,10 @@ impl UiInstance {
|
|||
});
|
||||
}
|
||||
|
||||
/// Reset the state from the previous frame, and prepare the UI for layout and processing\
|
||||
/// You must call this function at the start of the frame, before adding any elements\
|
||||
/// Reset the state from the previous frame, and prepare the UI for layout and processing
|
||||
///
|
||||
/// ## Panics:
|
||||
/// If called twice in a row (for example, if you forget to call [`UiInstance::end`])\
|
||||
/// This is an indication of a bug in your code and should be fixed.
|
||||
/// - You must call this function at the start of the frame, before adding any elements
|
||||
/// - Make sure to provide all of the events that happened since the last frame before calling this function, to avoid a 1-frame delay in event processing
|
||||
pub fn begin_frame(&mut self) {
|
||||
//first, drain and process the event queue
|
||||
self.input.update_state(&mut self.events);
|
||||
|
@ -182,6 +187,17 @@ impl UiInstance {
|
|||
self.paint_commands.clear();
|
||||
}
|
||||
|
||||
/// End rendering the current frame and present it
|
||||
///
|
||||
/// You must call this function sometime at the end of the frame, after adding all elements but before rendering, but before running the render backend
|
||||
pub fn end_frame(&mut self) {
|
||||
self.presentation.draw(&mut self.painter, &self.paint_commands);
|
||||
}
|
||||
|
||||
pub fn backend_data(&self) -> BackendData {
|
||||
self.painter.backend_data(&self.presentation)
|
||||
}
|
||||
|
||||
/// Push a platform event to the UI event queue
|
||||
///
|
||||
/// You should call this function *before* calling [`UiInstance::begin`] or after calling [`UiInstance::end`]\
|
||||
|
|
Loading…
Reference in a new issue