use bytemuck::{Pod, Zeroable};
use densa_core::Color;
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Pod, Zeroable)]
pub struct Instance {
pub rect: [f32; 4],
pub uv: [f32; 4],
pub color: [f32; 4],
}
impl Instance {
pub const fn solid(rect: [f32; 4], color: Color) -> Self {
Self {
rect,
uv: [0.0; 4],
color: color.to_array(),
}
}
pub const fn glyph(rect: [f32; 4], uv: [f32; 4], color: Color) -> Self {
Self {
rect,
uv,
color: color.to_array(),
}
}
pub fn is_glyph(&self) -> bool {
self.uv[2] > self.uv[0]
}
}
#[derive(Debug, Clone)]
pub struct InstanceBuffer {
items: Box<[Instance]>,
len: usize,
dropped: u64,
}
impl InstanceBuffer {
pub fn with_capacity(capacity: usize) -> Self {
Self {
items: vec![Instance::zeroed(); capacity].into_boxed_slice(),
len: 0,
dropped: 0,
}
}
pub fn clear(&mut self) {
self.len = 0;
self.dropped = 0;
}
#[inline]
pub fn push(&mut self, instance: Instance) -> bool {
match self.items.get_mut(self.len) {
Some(slot) => {
*slot = instance;
self.len += 1;
true
}
None => {
self.dropped += 1;
false
}
}
}
pub fn as_slice(&self) -> &[Instance] {
&self.items[..self.len]
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn capacity(&self) -> usize {
self.items.len()
}
pub fn dropped(&self) -> u64 {
self.dropped
}
}