layers initial impl (no sensors)

This commit is contained in:
2025-09-20 00:50:58 -04:00
parent 7651699743
commit 8ecd8bb171
7 changed files with 312 additions and 198 deletions

View File

@@ -3,6 +3,7 @@ use std::num::NonZero;
use crate::{
layout::Ui,
render::{data::PrimitiveInstance, texture::GpuTextures, util::ArrBuf},
util::HashMap,
};
use data::WindowUniform;
use wgpu::{
@@ -23,38 +24,76 @@ const SHAPE_SHADER: &str = include_str!("./shader.wgsl");
pub struct UiRenderer {
uniform_group: BindGroup,
primitive_layout: BindGroupLayout,
primitive_group: BindGroup,
rsc_layout: BindGroupLayout,
rsc_group: BindGroup,
pipeline: RenderPipeline,
layers: HashMap<usize, RenderLayer>,
active: Vec<usize>,
window_buffer: Buffer,
textures: GpuTextures,
}
struct RenderLayer {
instance: ArrBuf<PrimitiveInstance>,
primitives: PrimitiveBuffers,
textures: GpuTextures,
primitive_group: BindGroup,
}
impl UiRenderer {
pub fn draw<'a>(&'a self, pass: &mut RenderPass<'a>) {
if self.instance.len() == 0 {
return;
}
pass.set_pipeline(&self.pipeline);
pass.set_bind_group(0, &self.uniform_group, &[]);
pass.set_bind_group(1, &self.primitive_group, &[]);
pass.set_bind_group(2, &self.rsc_group, &[]);
pass.set_vertex_buffer(0, self.instance.buffer.slice(..));
pass.draw(0..4, 0..self.instance.len() as u32);
for i in &self.active {
let layer = &self.layers[i];
if layer.instance.len() == 0 {
continue;
}
pass.set_bind_group(1, &layer.primitive_group, &[]);
pass.set_vertex_buffer(0, layer.instance.buffer.slice(..));
pass.draw(0..4, 0..layer.instance.len() as u32);
}
}
pub fn update<Ctx>(&mut self, device: &Device, queue: &Queue, ui: &mut Ui<Ctx>) {
if ui.primitives.updated {
self.instance
.update(device, queue, ui.primitives.instances());
self.primitives.update(device, queue, ui.primitives.data());
self.primitive_group =
Self::primitive_group(device, &self.primitive_layout, self.primitives.buffers())
self.active.clear();
for (i, primitives) in ui.layers.iter_mut() {
self.active.push(i);
for change in primitives.apply_free() {
if let Some(inst) = ui.active.widgets.get_mut(&change.id) {
for h in &mut inst.primitives {
if h.inst_idx == change.old {
h.inst_idx = change.new;
break;
}
}
}
}
let layer = self.layers.entry(i).or_insert_with(|| {
let primitives = PrimitiveBuffers::new(device);
let primitive_group =
Self::primitive_group(device, &self.primitive_layout, primitives.buffers());
RenderLayer {
instance: ArrBuf::new(
device,
BufferUsages::VERTEX | BufferUsages::COPY_DST,
"instance",
),
primitives,
primitive_group,
}
});
if primitives.updated {
layer.instance.update(device, queue, primitives.instances());
layer.primitives.update(device, queue, primitives.data());
layer.primitive_group = Self::primitive_group(
device,
&self.primitive_layout,
layer.primitives.buffers(),
)
}
}
if self.textures.update(&mut ui.textures) {
self.rsc_group = Self::rsc_group(device, &self.rsc_layout, &self.textures)
@@ -87,13 +126,6 @@ impl UiRenderer {
usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST,
});
let instance = ArrBuf::new(
device,
BufferUsages::VERTEX | BufferUsages::COPY_DST,
"instance",
);
let primitives = PrimitiveBuffers::new(device);
let uniform_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
entries: &[BindGroupLayoutEntry {
binding: 0,
@@ -126,9 +158,6 @@ impl UiRenderer {
label: Some("primitive"),
});
let primitive_group =
Self::primitive_group(device, &primitive_layout, primitives.buffers());
let tex_manager = GpuTextures::new(device, queue);
let rsc_layout = Self::rsc_layout(device, &limits);
let rsc_group = Self::rsc_group(device, &rsc_layout, &tex_manager);
@@ -179,13 +208,12 @@ impl UiRenderer {
Self {
uniform_group,
primitive_layout,
primitive_group,
rsc_layout,
rsc_group,
pipeline,
window_buffer,
instance,
primitives,
layers: HashMap::default(),
active: Vec::new(),
textures: tex_manager,
}
}