scene.rs

  1use super::{Bounds, Hsla, Pixels, Point};
  2use crate::{Corners, Edges, FontId, GlyphId};
  3use bytemuck::{Pod, Zeroable};
  4use plane_split::BspSplitter;
  5
  6pub struct Scene {
  7    opaque_primitives: PrimitiveBatch,
  8    transparent_primitives: slotmap::SlotMap<slotmap::DefaultKey, Primitive>,
  9    splitter: BspSplitter<slotmap::DefaultKey>,
 10}
 11
 12impl Scene {
 13    pub fn new() -> Scene {
 14        Scene {
 15            opaque_primitives: PrimitiveBatch::default(),
 16            transparent_primitives: slotmap::SlotMap::new(),
 17            splitter: BspSplitter::new(),
 18        }
 19    }
 20
 21    pub fn insert(&mut self, primitive: impl Into<Primitive>, is_transparent: bool) {
 22        if is_transparent {
 23            self.transparent_primitives.insert(primitive.into());
 24        } else {
 25            match primitive.into() {
 26                Primitive::Quad(quad) => self.opaque_primitives.quads.push(quad),
 27                Primitive::Glyph(glyph) => self.opaque_primitives.glyphs.push(glyph),
 28                Primitive::Underline(underline) => {
 29                    self.opaque_primitives.underlines.push(underline)
 30                }
 31            }
 32        }
 33    }
 34
 35    pub fn opaque_primitives(&self) -> &PrimitiveBatch {
 36        &self.opaque_primitives
 37    }
 38}
 39
 40#[derive(Clone, Debug)]
 41pub enum Primitive {
 42    Quad(Quad),
 43    Glyph(RenderedGlyph),
 44    Underline(Underline),
 45}
 46
 47impl Primitive {
 48    pub fn is_transparent(&self) -> bool {
 49        match self {
 50            Primitive::Quad(quad) => {
 51                quad.background.is_transparent() && quad.border_color.is_transparent()
 52            }
 53            Primitive::Glyph(glyph) => glyph.color.is_transparent(),
 54            Primitive::Underline(underline) => underline.color.is_transparent(),
 55        }
 56    }
 57}
 58
 59#[derive(Default)]
 60pub struct PrimitiveBatch {
 61    pub quads: Vec<Quad>,
 62    pub glyphs: Vec<RenderedGlyph>,
 63    pub underlines: Vec<Underline>,
 64}
 65
 66#[derive(Debug, Clone, Copy)]
 67#[repr(C)]
 68pub struct Quad {
 69    pub order: f32,
 70    pub bounds: Bounds<Pixels>,
 71    pub clip_bounds: Bounds<Pixels>,
 72    pub clip_corner_radii: Corners<Pixels>,
 73    pub background: Hsla,
 74    pub border_color: Hsla,
 75    pub corner_radii: Corners<Pixels>,
 76    pub border_widths: Edges<Pixels>,
 77}
 78
 79impl Quad {
 80    pub fn vertices(&self) -> impl Iterator<Item = Point<Pixels>> {
 81        let x1 = self.bounds.origin.x;
 82        let y1 = self.bounds.origin.y;
 83        let x2 = x1 + self.bounds.size.width;
 84        let y2 = y1 + self.bounds.size.height;
 85        [
 86            Point::new(x1, y1),
 87            Point::new(x2, y1),
 88            Point::new(x2, y2),
 89            Point::new(x1, y2),
 90        ]
 91        .into_iter()
 92    }
 93}
 94
 95unsafe impl Zeroable for Quad {}
 96
 97unsafe impl Pod for Quad {}
 98
 99impl From<Quad> for Primitive {
100    fn from(quad: Quad) -> Self {
101        Primitive::Quad(quad)
102    }
103}
104
105#[derive(Debug, Clone, Copy)]
106#[repr(C)]
107pub(crate) struct QuadUniforms {
108    viewport_size: [f32; 2],
109}
110
111unsafe impl Zeroable for QuadUniforms {}
112
113unsafe impl Pod for QuadUniforms {}
114
115#[derive(Debug, Clone, Copy)]
116#[repr(C)]
117pub struct RenderedGlyph {
118    pub font_id: FontId,
119    pub font_size: f32,
120    pub id: GlyphId,
121    pub origin: Point<Pixels>,
122    pub color: Hsla,
123}
124
125impl From<RenderedGlyph> for Primitive {
126    fn from(glyph: RenderedGlyph) -> Self {
127        Primitive::Glyph(glyph)
128    }
129}
130
131#[derive(Copy, Clone, Default, Debug)]
132#[repr(C)]
133pub struct Underline {
134    pub origin: Point<Pixels>,
135    pub width: Pixels,
136    pub thickness: Pixels,
137    pub color: Hsla,
138    pub squiggly: bool,
139}
140
141unsafe impl Zeroable for Underline {}
142
143unsafe impl Pod for Underline {}
144
145impl From<Underline> for Primitive {
146    fn from(underline: Underline) -> Self {
147        Primitive::Underline(underline)
148    }
149}