Skip to content

Commit

Permalink
Add conversions from Color to u32 (#4088)
Browse files Browse the repository at this point in the history
# Objective

- `Mesh::ATTRIBUTE_COLOR` expects colors as `u32`s but there is no function for easy conversion.
- See #4037 (review)

## Solution

- Added `Color::as_rgba_u32` and `Color::as_linear_rgba_u32`
  • Loading branch information
Azorlogh committed Mar 8, 2022
1 parent e3a3b5b commit e36c9b6
Showing 1 changed file with 93 additions and 1 deletion.
94 changes: 93 additions & 1 deletion crates/bevy_render/src/color/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ impl Color {
}
}

/// Converts a `Color` to a `[f32; 4]` from linear RBG colorspace
/// Converts a `Color` to a `[f32; 4]` from linear RGB colorspace
#[inline]
pub fn as_linear_rgba_f32(self: Color) -> [f32; 4] {
match self {
Expand Down Expand Up @@ -487,6 +487,98 @@ impl Color {
} => [hue, saturation, lightness, alpha],
}
}

/// Converts Color to a u32 from sRGB colorspace.
///
/// Maps the RGBA channels in RGBA order to a little-endian byte array (GPUs are little-endian).
/// A will be the most significant byte and R the least significant.
pub fn as_rgba_u32(self: Color) -> u32 {
match self {
Color::Rgba {
red,
green,
blue,
alpha,
} => u32::from_le_bytes([
(red * 255.0) as u8,
(green * 255.0) as u8,
(blue * 255.0) as u8,
(alpha * 255.0) as u8,
]),
Color::RgbaLinear {
red,
green,
blue,
alpha,
} => u32::from_le_bytes([
(red.linear_to_nonlinear_srgb() * 255.0) as u8,
(green.linear_to_nonlinear_srgb() * 255.0) as u8,
(blue.linear_to_nonlinear_srgb() * 255.0) as u8,
(alpha * 255.0) as u8,
]),
Color::Hsla {
hue,
saturation,
lightness,
alpha,
} => {
let [red, green, blue] =
HslRepresentation::hsl_to_nonlinear_srgb(hue, saturation, lightness);
u32::from_le_bytes([
(red * 255.0) as u8,
(green * 255.0) as u8,
(blue * 255.0) as u8,
(alpha * 255.0) as u8,
])
}
}
}

/// Converts Color to a u32 from linear RGB colorspace.
///
/// Maps the RGBA channels in RGBA order to a little-endian byte array (GPUs are little-endian).
/// A will be the most significant byte and R the least significant.
pub fn as_linear_rgba_u32(self: Color) -> u32 {
match self {
Color::Rgba {
red,
green,
blue,
alpha,
} => u32::from_le_bytes([
(red.nonlinear_to_linear_srgb() * 255.0) as u8,
(green.nonlinear_to_linear_srgb() * 255.0) as u8,
(blue.nonlinear_to_linear_srgb() * 255.0) as u8,
(alpha * 255.0) as u8,
]),
Color::RgbaLinear {
red,
green,
blue,
alpha,
} => u32::from_le_bytes([
(red * 255.0) as u8,
(green * 255.0) as u8,
(blue * 255.0) as u8,
(alpha * 255.0) as u8,
]),
Color::Hsla {
hue,
saturation,
lightness,
alpha,
} => {
let [red, green, blue] =
HslRepresentation::hsl_to_nonlinear_srgb(hue, saturation, lightness);
u32::from_le_bytes([
(red.nonlinear_to_linear_srgb() * 255.0) as u8,
(green.nonlinear_to_linear_srgb() * 255.0) as u8,
(blue.nonlinear_to_linear_srgb() * 255.0) as u8,
(alpha * 255.0) as u8,
])
}
}
}
}

impl Default for Color {
Expand Down

0 comments on commit e36c9b6

Please sign in to comment.