Skip to main content

wisp_storybook/stories/
s_mask_combine.rs

1//! Story: mask boolean operations (M-VEC.11 / AUT-63).
2//!
3//! Three side-by-side tiles showing the result of combining two
4//! overlapping circle masks with `Union`, `Intersect`, and `Subtract`.
5
6use glam::Vec2;
7use wisp::application::Application;
8use wisp::render::Renderer;
9use wisp::{MaskCombineOp, MaskShape, RenderTexture, Sprite, Stage, Texture};
10
11use crate::story::Story;
12
13pub fn story() -> Story {
14    Story {
15        id: "mask-combine",
16        category: "Mask",
17        title: "Mask boolean ops",
18        milestone: "M-VEC.11 / AUT-63",
19        writeup: include_str!("writeups/mask_combine.md"),
20        build,
21        tick: None,
22    }
23}
24
25fn build(app: &Application, stage: &mut Stage) {
26    let format = wgpu::TextureFormat::Rgba8Unorm;
27    let renderer = Renderer::new(app, format).expect("renderer");
28
29    let tile_size: u32 = 192;
30
31    let a_shape = MaskShape::circle(Vec2::new(-0.25, 0.0), 0.55);
32    let b_shape = MaskShape::circle(Vec2::new(0.25, 0.0), 0.55);
33    let a = renderer.generate_mask_texture(app, a_shape, tile_size, tile_size);
34    let b = renderer.generate_mask_texture(app, b_shape, tile_size, tile_size);
35
36    let ops_and_positions = [
37        (MaskCombineOp::Union, Vec2::new(-0.62, 0.0)),
38        (MaskCombineOp::Intersect, Vec2::new(0.0, 0.0)),
39        (MaskCombineOp::Subtract, Vec2::new(0.62, 0.0)),
40    ];
41
42    for (op, pos) in ops_and_positions {
43        let combined = RenderTexture::with_format(app, tile_size, tile_size, format);
44        renderer.combine_masks(app, &a, &b, op, &combined);
45
46        let bytes = combined.read_pixels(app);
47        let tex = Texture::from_rgba(app, tile_size, tile_size, &bytes);
48        let mut sprite = Sprite::from_texture(tex).with_anchor(Vec2::splat(0.5));
49        sprite.container.transform.position = pos;
50        sprite.container.transform.scale = Vec2::splat(0.28);
51        let _ = stage.add_child(stage.root(), sprite);
52    }
53}