wisp_storybook/stories/
s_text_composition.rs1use glam::Vec2;
5use wisp::application::Application;
6use wisp::blend::BlendMode;
7use wisp::filter::ColorMatrixFilter;
8use wisp::render::Renderer;
9use wisp::text::{TextTexturePipeline, WispText, WispTextStyle};
10use wisp::texture::render_texture::RenderTexture;
11use wisp::{Color, Sprite, Stage, WispFontWeight};
12
13use crate::story::Story;
14
15pub fn story() -> Story {
16 Story {
17 id: "text-composition",
18 category: "Scene Graph",
19 title: "Text + filter + blend composition",
20 milestone: "M-TEXT.6",
21 writeup: include_str!("writeups/text_composition.md"),
22 build,
23 tick: None,
24 }
25}
26
27fn build(app: &Application, stage: &mut Stage) {
28 let pipeline = TextTexturePipeline::new(app, wgpu::TextureFormat::Rgba8UnormSrgb);
29
30 let backdrop_rt = {
33 let renderer = Renderer::new(app, wgpu::TextureFormat::Rgba8UnormSrgb).expect("renderer");
34 let rt = RenderTexture::with_format(app, 256, 256, wgpu::TextureFormat::Rgba8UnormSrgb);
35 let empty = Stage::new();
36 let _ = renderer.render_stage(app, rt.view(), Color::rgba(0.85, 0.35, 0.25, 1.0), &empty);
37 rt
38 };
39 let mut backdrop = Sprite::from_texture(backdrop_rt.as_texture());
40 backdrop.container.transform.position = Vec2::new(-1.0, -1.0);
41 backdrop.container.transform.scale = Vec2::new(2.0, 2.0);
42 let _ = stage.add_child(stage.root(), backdrop);
43
44 let normal_text = WispText::new("Normal").with_style(
46 WispTextStyle::default()
47 .with_size(0.35)
48 .with_weight(WispFontWeight::Bold)
49 .with_color(Color::WHITE),
50 );
51 let normal_rt = pipeline.render(app, &normal_text, 512, 192);
52 let mut normal_sprite =
53 Sprite::from_texture(normal_rt.as_texture()).with_anchor(Vec2::new(0.5, 0.5));
54 normal_sprite.container.transform.position = Vec2::new(0.0, 0.5);
55 normal_sprite.container.transform.scale = Vec2::new(1.4, -0.45);
56 normal_sprite.container.blend_mode = BlendMode::Normal;
57 let _ = stage.add_child(stage.root(), normal_sprite);
58
59 let sub_text = WispText::new("Subtract").with_style(
64 WispTextStyle::default()
65 .with_size(0.35)
66 .with_weight(WispFontWeight::Bold)
67 .with_color(Color::WHITE),
68 );
69 let sub_rt = pipeline.render(app, &sub_text, 512, 192);
70 let mut sub_sprite = Sprite::from_texture(sub_rt.as_texture()).with_anchor(Vec2::new(0.5, 0.5));
71 sub_sprite.container.transform.position = Vec2::new(0.0, 0.0);
72 sub_sprite.container.transform.scale = Vec2::new(1.4, -0.45);
73 sub_sprite.container.blend_mode = BlendMode::Subtract;
74 let _ = stage.add_child(stage.root(), sub_sprite);
75
76 let orange_text = WispText::new("Filtered").with_style(
80 WispTextStyle::default()
81 .with_size(0.35)
82 .with_weight(WispFontWeight::Bold)
83 .with_color(Color::rgba(1.0, 0.4, 0.1, 1.0)),
84 );
85 let source = pipeline.render(app, &orange_text, 512, 192);
86 let filtered = RenderTexture::with_format(app, 512, 192, wgpu::TextureFormat::Rgba8UnormSrgb);
87 {
88 let renderer = Renderer::new(app, wgpu::TextureFormat::Rgba8UnormSrgb).expect("renderer");
89 renderer.apply_filter(app, &ColorMatrixFilter::grayscale(), &source, &filtered);
90 }
91 let mut filtered_sprite =
92 Sprite::from_texture(filtered.as_texture()).with_anchor(Vec2::new(0.5, 0.5));
93 filtered_sprite.container.transform.position = Vec2::new(0.0, -0.5);
94 filtered_sprite.container.transform.scale = Vec2::new(1.4, -0.45);
95 let _ = stage.add_child(stage.root(), filtered_sprite);
96}