use nalgebra_glm::Vec2;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
pub enum SpriteBlendMode {
Alpha,
Additive,
Multiply,
Screen,
Overlay,
Darken,
Lighten,
ColorDodge,
ColorBurn,
Difference,
Exclusion,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
pub enum SpriteStencilMode {
None,
Write,
Test,
}
impl Default for SpriteStencilMode {
fn default() -> Self {
Self::None
}
}
impl Default for SpriteBlendMode {
fn default() -> Self {
Self::Alpha
}
}
impl SpriteBlendMode {
pub fn is_advanced(self) -> bool {
matches!(
self,
Self::Overlay
| Self::Darken
| Self::Lighten
| Self::ColorDodge
| Self::ColorBurn
| Self::Difference
| Self::Exclusion
)
}
pub fn advanced_blend_index(self) -> u32 {
match self {
Self::Overlay => 1,
Self::Darken => 2,
Self::Lighten => 3,
Self::ColorDodge => 4,
Self::ColorBurn => 5,
Self::Difference => 6,
Self::Exclusion => 7,
_ => 0,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum SpriteGradient {
None,
Linear { angle: f32 },
Radial { center: Vec2 },
}
impl Default for SpriteGradient {
fn default() -> Self {
Self::None
}
}
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
pub struct NineSlice {
pub left: f32,
pub right: f32,
pub top: f32,
pub bottom: f32,
}
impl NineSlice {
pub fn new(left: f32, right: f32, top: f32, bottom: f32) -> Self {
Self {
left,
right,
top,
bottom,
}
}
pub fn uniform(border: f32) -> Self {
Self {
left: border,
right: border,
top: border,
bottom: border,
}
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Sprite {
pub position: Vec2,
pub size: Vec2,
pub color: [f32; 4],
pub texture_index: u32,
pub texture_index2: u32,
pub blend_factor: f32,
pub uv_min: Vec2,
pub uv_max: Vec2,
pub rotation: f32,
pub depth: f32,
pub scale: Vec2,
pub flip_x: bool,
pub flip_y: bool,
pub anchor: Vec2,
pub blend_mode: SpriteBlendMode,
pub nine_slice: Option<NineSlice>,
pub clip_rect: Option<[f32; 4]>,
pub stencil_mode: SpriteStencilMode,
pub stencil_reference: u8,
pub gradient: SpriteGradient,
}
impl Default for Sprite {
fn default() -> Self {
Self {
position: Vec2::new(0.0, 0.0),
size: Vec2::new(100.0, 100.0),
color: [1.0, 1.0, 1.0, 1.0],
texture_index: 0,
texture_index2: 0,
blend_factor: 0.0,
uv_min: Vec2::new(0.0, 0.0),
uv_max: Vec2::new(1.0, 1.0),
rotation: 0.0,
depth: 0.0,
scale: Vec2::new(1.0, 1.0),
flip_x: false,
flip_y: false,
anchor: Vec2::new(0.0, 0.0),
blend_mode: SpriteBlendMode::Alpha,
nine_slice: None,
clip_rect: None,
stencil_mode: SpriteStencilMode::None,
stencil_reference: 1,
gradient: SpriteGradient::None,
}
}
}
impl Sprite {
pub fn new(position: Vec2, size: Vec2) -> Self {
Self {
position,
size,
..Default::default()
}
}
pub fn with_texture(mut self, texture_index: u32) -> Self {
self.texture_index = texture_index;
self.texture_index2 = texture_index;
self
}
pub fn with_multitexture(
mut self,
texture_index: u32,
texture_index2: u32,
blend_factor: f32,
) -> Self {
self.texture_index = texture_index;
self.texture_index2 = texture_index2;
self.blend_factor = blend_factor;
self
}
pub fn with_color(mut self, color: [f32; 4]) -> Self {
self.color = color;
self
}
pub fn with_rotation(mut self, rotation: f32) -> Self {
self.rotation = rotation;
self
}
pub fn with_scale(mut self, scale: Vec2) -> Self {
self.scale = scale;
self
}
pub fn with_depth(mut self, depth: f32) -> Self {
self.depth = depth;
self
}
pub fn with_flip_x(mut self, flip_x: bool) -> Self {
self.flip_x = flip_x;
self
}
pub fn with_flip_y(mut self, flip_y: bool) -> Self {
self.flip_y = flip_y;
self
}
pub fn with_anchor(mut self, anchor: Vec2) -> Self {
self.anchor = anchor;
self
}
pub fn with_blend_mode(mut self, blend_mode: SpriteBlendMode) -> Self {
self.blend_mode = blend_mode;
self
}
pub fn with_nine_slice(mut self, nine_slice: NineSlice) -> Self {
self.nine_slice = Some(nine_slice);
self
}
pub fn with_clip_rect(mut self, clip_rect: [f32; 4]) -> Self {
self.clip_rect = Some(clip_rect);
self
}
pub fn with_stencil_mode(mut self, stencil_mode: SpriteStencilMode) -> Self {
self.stencil_mode = stencil_mode;
self
}
pub fn with_stencil_reference(mut self, reference: u8) -> Self {
self.stencil_reference = reference;
self
}
pub fn with_gradient(mut self, gradient: SpriteGradient) -> Self {
self.gradient = gradient;
self
}
}