1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
use crate::pixel::Rgba; use crate::render::{Render, RenderOpt}; use crate::path::Path; #[derive(Debug)] pub enum CompositeMode { None, Normal(Path) } pub struct Composite { pub layers: Vec<(Box<Render<Rgba>>, CompositeMode)> } impl Render<Rgba> for Composite { fn sample(&self, u: f64, v: f64, time: f64) -> Rgba { let mut value = Rgba::default(); for (render, cm) in &self.layers { composite(&mut [value], &[render.sample(u, v, time)], time, cm); } value } fn render(&self, ro: &RenderOpt, buffer: &mut [Rgba]) { let RenderOpt {u_res, v_res, frame_range, framerate, ..} = ro; let mut sub_buffer = vec![Rgba::default(); buffer.len()]; let frame_size = u_res * v_res; for (render, cm) in &self.layers { render.render(ro, sub_buffer.as_mut_slice()); for f in frame_range.start..frame_range.end { let start = frame_size * (f - frame_range.start) as usize; composite( &mut buffer[start..start+frame_size], &sub_buffer[start..start+frame_size], f as f64 / *framerate as f64, cm); } } } } #[inline(always)] fn composite(base: &mut [Rgba], value: &[Rgba], time: f64, cm: &CompositeMode) { match cm { CompositeMode::None => { for i in 0..base.len() { base[i] = value[i]; } }, CompositeMode::Normal(alpha_path) => { let alpha = alpha_path.get_value(time); for i in 0..base.len() { base[i] = base[i].normal_blend(&value[i], alpha); } } }; }