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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use {
    super::Color,
    crate::math::{vec4, Vec4},
    gfx_hal::{
        command::{ClearColor, ClearValue},
        image::PackedColor,
    },
    std::u8,
};

/// Black with zero alpha - 0x00000000
pub const TRANSPARENT_BLACK: AlphaColor = AlphaColor::rgba(0, 0, 0, 0);

/// A four channel (with alpha) color.
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct AlphaColor {
    /// Alpha channel.
    pub a: u8,

    /// Blue channel.
    pub b: u8,

    /// Green channel.
    pub g: u8,

    /// Red channel.
    pub r: u8,
}

impl AlphaColor {
    /// Returns true if the alpha channel is non-zero
    pub fn is_transparent(self) -> bool {
        self.a < u8::MAX
    }

    /// Constructs an `AlphaColor` from the given values.
    pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
        Self { b, g, r, a: 0xff }
    }

    /// Constructs an `AlphaColor` from the given values.
    pub const fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
        Self { b, g, r, a }
    }

    /// Constructs a `Vec4` from this color.
    pub fn to_rgba(self) -> Vec4 {
        const SCALE: f32 = 1.0 / u8::MAX as f32;

        vec4(
            self.r as f32 * SCALE,
            self.g as f32 * SCALE,
            self.b as f32 * SCALE,
            self.a as f32 * SCALE,
        )
    }
}

impl Default for AlphaColor {
    fn default() -> Self {
        TRANSPARENT_BLACK
    }
}

impl From<Color> for AlphaColor {
    fn from(color: Color) -> Self {
        Self {
            a: 0xff,
            b: color.b,
            g: color.g,
            r: color.r,
        }
    }
}

impl From<AlphaColor> for ClearValue {
    fn from(color: AlphaColor) -> Self {
        let color = color.to_rgba();
        Self {
            color: ClearColor {
                float32: [color.x, color.y, color.z, color.w],
            },
        }
    }
}

impl From<AlphaColor> for PackedColor {
    fn from(color: AlphaColor) -> Self {
        Self(
            (color.r as u32) << 24
                | (color.g as u32) << 16
                | (color.b as u32) << 8
                | (color.a as u32),
        )
    }
}