2021-09-01 05:46:28 +10:00
|
|
|
//! Various synthetic scenes for exercising the renderer.
|
|
|
|
|
|
|
|
use rand::{Rng, RngCore};
|
|
|
|
|
2022-03-17 08:40:58 +11:00
|
|
|
use crate::{Blend, BlendMode, CompositionMode, PietGpuRenderContext};
|
2022-03-01 04:38:14 +11:00
|
|
|
use piet::kurbo::{Affine, BezPath, Circle, Line, Point, Rect, Shape};
|
2021-09-07 03:19:55 +10:00
|
|
|
use piet::{
|
|
|
|
Color, FixedGradient, FixedLinearGradient, GradientStop, Text, TextAttribute, TextLayoutBuilder,
|
|
|
|
};
|
2021-09-01 05:46:28 +10:00
|
|
|
|
2021-09-07 03:19:55 +10:00
|
|
|
use crate::{PicoSvg, RenderContext, Vec2};
|
2021-09-01 05:46:28 +10:00
|
|
|
|
|
|
|
const N_CIRCLES: usize = 0;
|
|
|
|
|
2022-03-01 04:38:14 +11:00
|
|
|
pub fn render_blend_test(rc: &mut PietGpuRenderContext, i: usize, blend: Blend) {
|
2022-03-17 08:40:58 +11:00
|
|
|
rc.fill(Rect::new(400., 400., 800., 800.), &Color::rgb8(0, 0, 200));
|
2022-03-01 04:38:14 +11:00
|
|
|
rc.save().unwrap();
|
|
|
|
rc.blend(Rect::new(0., 0., 1000., 1000.), blend);
|
|
|
|
rc.transform(Affine::translate(Vec2::new(600., 600.)) * Affine::rotate(0.01 * i as f64));
|
|
|
|
rc.fill(Rect::new(0., 0., 400., 400.), &Color::rgba8(255, 0, 0, 255));
|
|
|
|
rc.restore().unwrap();
|
|
|
|
}
|
|
|
|
|
2021-09-01 05:46:28 +10:00
|
|
|
pub fn render_svg(rc: &mut impl RenderContext, filename: &str, scale: f64) {
|
|
|
|
let xml_str = std::fs::read_to_string(filename).unwrap();
|
|
|
|
let start = std::time::Instant::now();
|
|
|
|
let svg = PicoSvg::load(&xml_str, scale).unwrap();
|
|
|
|
println!("parsing time: {:?}", start.elapsed());
|
|
|
|
|
|
|
|
let start = std::time::Instant::now();
|
|
|
|
svg.render(rc);
|
|
|
|
println!("flattening and encoding time: {:?}", start.elapsed());
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn render_scene(rc: &mut impl RenderContext) {
|
|
|
|
const WIDTH: usize = 2048;
|
|
|
|
const HEIGHT: usize = 1536;
|
|
|
|
let mut rng = rand::thread_rng();
|
|
|
|
for _ in 0..N_CIRCLES {
|
|
|
|
let color = Color::from_rgba32_u32(rng.next_u32());
|
|
|
|
let center = Point::new(
|
|
|
|
rng.gen_range(0.0, WIDTH as f64),
|
|
|
|
rng.gen_range(0.0, HEIGHT as f64),
|
|
|
|
);
|
|
|
|
let radius = rng.gen_range(0.0, 50.0);
|
|
|
|
let circle = Circle::new(center, radius);
|
|
|
|
rc.fill(circle, &color);
|
|
|
|
}
|
|
|
|
let _ = rc.save();
|
|
|
|
let mut path = BezPath::new();
|
|
|
|
path.move_to((200.0, 150.0));
|
|
|
|
path.line_to((100.0, 200.0));
|
|
|
|
path.line_to((150.0, 250.0));
|
|
|
|
path.close_path();
|
|
|
|
rc.clip(path);
|
|
|
|
|
|
|
|
let mut path = BezPath::new();
|
|
|
|
path.move_to((100.0, 150.0));
|
|
|
|
path.line_to((200.0, 200.0));
|
|
|
|
path.line_to((150.0, 250.0));
|
|
|
|
path.close_path();
|
|
|
|
rc.fill(path, &Color::rgb8(128, 0, 128));
|
|
|
|
let _ = rc.restore();
|
|
|
|
rc.stroke(
|
|
|
|
piet::kurbo::Line::new((100.0, 100.0), (200.0, 150.0)),
|
|
|
|
&Color::WHITE,
|
|
|
|
5.0,
|
|
|
|
);
|
|
|
|
//render_cardioid(rc);
|
|
|
|
render_clip_test(rc);
|
|
|
|
render_alpha_test(rc);
|
|
|
|
render_gradient_test(rc);
|
|
|
|
render_text_test(rc);
|
|
|
|
//render_tiger(rc);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(unused)]
|
|
|
|
fn render_cardioid(rc: &mut impl RenderContext) {
|
|
|
|
let n = 601;
|
|
|
|
let dth = std::f64::consts::PI * 2.0 / (n as f64);
|
|
|
|
let center = Point::new(1024.0, 768.0);
|
|
|
|
let r = 750.0;
|
|
|
|
let mut path = BezPath::new();
|
|
|
|
for i in 1..n {
|
|
|
|
let p0 = center + Vec2::from_angle(i as f64 * dth) * r;
|
|
|
|
let p1 = center + Vec2::from_angle(((i * 2) % n) as f64 * dth) * r;
|
|
|
|
//rc.fill(&Circle::new(p0, 8.0), &Color::WHITE);
|
|
|
|
path.move_to(p0);
|
|
|
|
path.line_to(p1);
|
|
|
|
//rc.stroke(Line::new(p0, p1), &Color::BLACK, 2.0);
|
|
|
|
}
|
|
|
|
rc.stroke(&path, &Color::BLACK, 2.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(unused)]
|
|
|
|
fn render_clip_test(rc: &mut impl RenderContext) {
|
|
|
|
const N: usize = 16;
|
|
|
|
const X0: f64 = 50.0;
|
|
|
|
const Y0: f64 = 450.0;
|
|
|
|
// Note: if it gets much larger, it will exceed the 1MB scratch buffer.
|
|
|
|
// But this is a pretty demanding test.
|
|
|
|
const X1: f64 = 550.0;
|
|
|
|
const Y1: f64 = 950.0;
|
|
|
|
let step = 1.0 / ((N + 1) as f64);
|
|
|
|
for i in 0..N {
|
|
|
|
let t = ((i + 1) as f64) * step;
|
|
|
|
rc.save();
|
|
|
|
let mut path = BezPath::new();
|
|
|
|
path.move_to((X0, Y0));
|
|
|
|
path.line_to((X1, Y0));
|
|
|
|
path.line_to((X1, Y0 + t * (Y1 - Y0)));
|
|
|
|
path.line_to((X1 + t * (X0 - X1), Y1));
|
|
|
|
path.line_to((X0, Y1));
|
|
|
|
path.close_path();
|
|
|
|
rc.clip(path);
|
|
|
|
}
|
|
|
|
let rect = piet::kurbo::Rect::new(X0, Y0, X1, Y1);
|
|
|
|
rc.fill(rect, &Color::BLACK);
|
|
|
|
for _ in 0..N {
|
|
|
|
rc.restore();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(unused)]
|
|
|
|
fn render_alpha_test(rc: &mut impl RenderContext) {
|
|
|
|
// Alpha compositing tests.
|
|
|
|
rc.fill(
|
|
|
|
diamond(Point::new(1024.0, 100.0)),
|
|
|
|
&Color::Rgba32(0xff0000ff),
|
|
|
|
);
|
|
|
|
rc.fill(
|
|
|
|
diamond(Point::new(1024.0, 125.0)),
|
|
|
|
&Color::Rgba32(0x00ff0080),
|
|
|
|
);
|
|
|
|
rc.save();
|
|
|
|
rc.clip(diamond(Point::new(1024.0, 150.0)));
|
|
|
|
rc.fill(
|
|
|
|
diamond(Point::new(1024.0, 175.0)),
|
|
|
|
&Color::Rgba32(0x0000ff80),
|
|
|
|
);
|
|
|
|
rc.restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(unused)]
|
|
|
|
fn render_gradient_test(rc: &mut impl RenderContext) {
|
|
|
|
let stops = vec![
|
|
|
|
GradientStop {
|
|
|
|
color: Color::rgb8(0, 255, 0),
|
|
|
|
pos: 0.0,
|
|
|
|
},
|
|
|
|
GradientStop {
|
|
|
|
color: Color::BLACK,
|
|
|
|
pos: 1.0,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
let lin = FixedLinearGradient {
|
|
|
|
start: Point::new(0.0, 100.0),
|
|
|
|
end: Point::new(0.0, 300.0),
|
|
|
|
stops,
|
|
|
|
};
|
|
|
|
let brush = FixedGradient::Linear(lin);
|
|
|
|
//let brush = Color::rgb8(0, 128, 0);
|
|
|
|
rc.fill(Rect::new(100.0, 100.0, 300.0, 300.0), &brush);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn diamond(origin: Point) -> impl Shape {
|
|
|
|
let mut path = BezPath::new();
|
|
|
|
const SIZE: f64 = 50.0;
|
|
|
|
path.move_to((origin.x, origin.y - SIZE));
|
|
|
|
path.line_to((origin.x + SIZE, origin.y));
|
|
|
|
path.line_to((origin.x, origin.y + SIZE));
|
|
|
|
path.line_to((origin.x - SIZE, origin.y));
|
|
|
|
path.close_path();
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(unused)]
|
|
|
|
fn render_text_test(rc: &mut impl RenderContext) {
|
|
|
|
rc.save();
|
|
|
|
//rc.transform(Affine::new([0.2, 0.0, 0.0, -0.2, 200.0, 800.0]));
|
|
|
|
let layout = rc
|
|
|
|
.text()
|
|
|
|
.new_text_layout("\u{1f600}hello piet-gpu text!")
|
|
|
|
.default_attribute(TextAttribute::FontSize(100.0))
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
|
|
|
rc.draw_text(&layout, Point::new(110.0, 600.0));
|
|
|
|
rc.draw_text(&layout, Point::new(110.0, 700.0));
|
|
|
|
rc.restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(unused)]
|
|
|
|
fn render_tiger(rc: &mut impl RenderContext) {
|
|
|
|
let xml_str = std::str::from_utf8(include_bytes!("../Ghostscript_Tiger.svg")).unwrap();
|
|
|
|
let start = std::time::Instant::now();
|
|
|
|
let svg = PicoSvg::load(xml_str, 8.0).unwrap();
|
|
|
|
println!("parsing time: {:?}", start.elapsed());
|
|
|
|
|
|
|
|
let start = std::time::Instant::now();
|
|
|
|
svg.render(rc);
|
|
|
|
println!("flattening and encoding time: {:?}", start.elapsed());
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn render_anim_frame(rc: &mut impl RenderContext, i: usize) {
|
2021-09-07 03:19:55 +10:00
|
|
|
rc.fill(
|
|
|
|
Rect::new(0.0, 0.0, 1000.0, 1000.0),
|
|
|
|
&Color::rgb8(128, 128, 128),
|
|
|
|
);
|
2021-09-01 05:46:28 +10:00
|
|
|
let text_size = 60.0 + 40.0 * (0.01 * i as f64).sin();
|
|
|
|
rc.save().unwrap();
|
|
|
|
//rc.transform(Affine::new([0.2, 0.0, 0.0, -0.2, 200.0, 800.0]));
|
|
|
|
let layout = rc
|
|
|
|
.text()
|
|
|
|
.new_text_layout("\u{1f600}hello piet-gpu text!")
|
|
|
|
.default_attribute(TextAttribute::FontSize(text_size))
|
|
|
|
.build()
|
|
|
|
.unwrap();
|
|
|
|
rc.draw_text(&layout, Point::new(110.0, 600.0));
|
|
|
|
rc.draw_text(&layout, Point::new(110.0, 700.0));
|
|
|
|
rc.restore().unwrap();
|
|
|
|
let th = (std::f64::consts::PI / 180.0) * (i as f64);
|
|
|
|
let center = Point::new(500.0, 500.0);
|
|
|
|
let p1 = center + 400.0 * Vec2::from_angle(th);
|
|
|
|
let line = Line::new(center, p1);
|
|
|
|
rc.stroke(line, &Color::rgb8(128, 0, 0), 5.0);
|
2021-09-07 03:19:55 +10:00
|
|
|
}
|