typed primitive buffers + macro for creation

This commit is contained in:
2025-08-21 19:37:50 -04:00
parent b7f83b58a9
commit bde929b05a
5 changed files with 190 additions and 105 deletions

View File

@@ -1,7 +1,9 @@
const RECT: u32 = 0;
@group(0) @binding(0)
var<uniform> window: WindowUniform;
@group(0) @binding(1)
var<storage> data: array<u32>;
@group(1) @binding(RECT)
var<storage> rects: array<RoundedRect>;
struct WindowUniform {
dim: vec2<f32>,
@@ -12,7 +14,8 @@ struct InstanceInput {
@location(1) top_left_offset: vec2<f32>,
@location(2) bottom_right_anchor: vec2<f32>,
@location(3) bottom_right_offset: vec2<f32>,
@location(4) pointer: u32,
@location(4) binding: u32,
@location(5) idx: u32,
}
struct RoundedRect {
@@ -23,9 +26,10 @@ struct RoundedRect {
}
struct VertexOutput {
@location(0) pointer: u32,
@location(1) top_left: vec2<f32>,
@location(2) bot_right: vec2<f32>,
@location(0) top_left: vec2<f32>,
@location(1) bot_right: vec2<f32>,
@location(2) binding: u32,
@location(3) idx: u32,
@builtin(position) clip_position: vec4<f32>,
};
@@ -52,7 +56,8 @@ fn vs_main(
) * size;
pos = pos / window.dim * 2.0 - 1.0;
out.clip_position = vec4<f32>(pos.x, -pos.y, 0.0, 1.0);
out.pointer = in.pointer;
out.binding = in.binding;
out.idx = in.idx;
out.top_left = top_left;
out.bot_right = bot_right;
@@ -64,25 +69,20 @@ fn fs_main(
in: VertexOutput
) -> @location(0) vec4<f32> {
let pos = in.clip_position.xy;
let ty = data[in.pointer];
let dp = in.pointer + 1u;
let region = Region(pos, in.top_left, in.bot_right);
switch ty {
case 0u: {
return draw_rounded_rect(region, RoundedRect(
data[dp + 0u],
bitcast<f32>(data[dp + 1u]),
bitcast<f32>(data[dp + 2u]),
bitcast<f32>(data[dp + 3u]),
));
let i = in.idx;
switch in.binding {
case RECT: {
return draw_rounded_rect(region, rects[i]);
}
default: {
return vec4(1.0, 0.0, 1.0, 1.0);
}
default: {}
}
return vec4(1.0, 0.0, 1.0, 1.0);
}
fn draw_rounded_rect(region: Region, rect: RoundedRect) -> vec4<f32> {
var color = unpack4x8unorm(rect.color);
var color = read_color(rect.color);
let edge = 0.5;
@@ -108,3 +108,21 @@ fn distance_from_rect(pixel_pos: vec2<f32>, rect_center: vec2<f32>, rect_corner:
let q = abs(p) - (rect_corner - radius);
return length(max(q, vec2<f32>(0.0, 0.0))) - radius;
}
fn read_color(c: u32) -> vec4<f32> {
let color = unpack4x8unorm(c);
return vec4(
srgb_to_linear(color.r),
srgb_to_linear(color.g),
srgb_to_linear(color.b),
color.a,
);
}
fn srgb_to_linear(c: f32) -> f32 {
if c <= 0.04045 {
return c / 12.92;
} else {
return pow((c + 0.055) / 1.055, 2.4);
}
}