Wire live serial data into matrix renderer

This commit is contained in:
lennlouisgeek
2026-05-20 01:23:02 +08:00
parent a7b617419d
commit d2c9fad556
18 changed files with 874 additions and 63 deletions

View File

@@ -6,10 +6,13 @@ use eframe::{
use crate::matrix::{MatrixLayout, build_view_projection, glyph_world_position};
pub const PRESSURE_CELL_COUNT: usize =
(crate::matrix::MATRIX_ROWS * crate::matrix::MATRIX_COLS) as usize;
pub struct WgpuBackgroundCallback {
pub width: f32,
pub height: f32,
pub time: f32,
pub pressure: [f32; PRESSURE_CELL_COUNT],
}
impl egui_wgpu::CallbackTrait for WgpuBackgroundCallback {
@@ -22,7 +25,7 @@ impl egui_wgpu::CallbackTrait for WgpuBackgroundCallback {
resources: &mut egui_wgpu::CallbackResources,
) -> Vec<wgpu::CommandBuffer> {
let resources: &mut BackgroundRenderResources = resources.get_mut().unwrap();
resources.prepare(queue, self.width, self.height, self.time);
resources.prepare(queue, self.width, self.height, &self.pressure);
Vec::new()
}
@@ -123,7 +126,7 @@ impl BackgroundRenderResources {
usage: wgpu::BufferUsages::VERTEX,
});
let glyph_instances = build_glyph_instances(rows, cols, &layout, 0.0);
let glyph_instances = build_glyph_instances(rows, cols, &layout, &[]);
let glyph_instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Pressure Glyph Instance Buffer"),
contents: bytemuck::cast_slice(&glyph_instances),
@@ -145,7 +148,7 @@ impl BackgroundRenderResources {
}
}
fn prepare(&mut self, queue: &wgpu::Queue, width: f32, height: f32, time: f32) {
fn prepare(&mut self, queue: &wgpu::Queue, width: f32, height: f32, pressure: &[f32]) {
let aspect = width / height.max(1.0);
self.uniform =
MatrixUniform::new(width, height, build_view_projection(aspect, &self.layout));
@@ -155,7 +158,13 @@ impl BackgroundRenderResources {
bytemuck::cast_slice(&[self.uniform]),
);
self.glyph_instances = build_glyph_instances(self.rows, self.cols, &self.layout, time);
update_glyph_instances(
&mut self.glyph_instances,
self.rows,
self.cols,
&self.layout,
pressure,
);
queue.write_buffer(
&self.glyph_instance_buffer,
0,
@@ -246,14 +255,16 @@ fn build_glyph_instances(
rows: u32,
cols: u32,
layout: &MatrixLayout,
time: f32,
pressure: &[f32],
) -> Vec<GlyphInstance> {
let mut instances = Vec::with_capacity((rows * cols) as usize);
for row in 0..rows {
for col in 0..cols {
let index = (row * cols + col) as usize;
let normalized = pressure.get(index).copied().unwrap_or(0.0);
let (world_position, normalized) =
glyph_world_position(row, col, rows, cols, layout, time);
glyph_world_position(row, col, rows, cols, layout, normalized);
instances.push(GlyphInstance {
world_position,
style: [normalized, 0.0, 0.0, 0.0],
@@ -264,6 +275,27 @@ fn build_glyph_instances(
instances
}
fn update_glyph_instances(
instances: &mut [GlyphInstance],
rows: u32,
cols: u32,
layout: &MatrixLayout,
pressure: &[f32],
) {
for row in 0..rows {
for col in 0..cols {
let index = (row * cols + col) as usize;
let normalized = pressure.get(index).copied().unwrap_or(0.0);
let (world_position, normalized) =
glyph_world_position(row, col, rows, cols, layout, normalized);
if let Some(instance) = instances.get_mut(index) {
instance.world_position = world_position;
instance.style = [normalized, 0.0, 0.0, 0.0];
}
}
}
}
#[repr(C)]
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
struct MatrixUniform {