Document the lights crate better
This commit is contained in:
parent
4f08a72d70
commit
766f421a31
3 changed files with 27 additions and 0 deletions
|
@ -25,6 +25,7 @@ static GAMMA_LOOKUP: &[u8] = &[
|
|||
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255
|
||||
];
|
||||
|
||||
/// Convert a perceptually-uniform RGB color into its "real" brightness for display.
|
||||
#[inline]
|
||||
pub fn correct(rgb: &Rgb) -> HardwareRgb {
|
||||
HardwareRgb(
|
||||
|
@ -34,6 +35,8 @@ pub fn correct(rgb: &Rgb) -> HardwareRgb {
|
|||
)
|
||||
}
|
||||
|
||||
/// Wraps a [Lights] implementation that takes [HardwareRgb] pixels,
|
||||
/// gamma-correcting [Rgb] pixels
|
||||
pub struct GammaCorrector<T>(pub T);
|
||||
|
||||
impl<T> Lights for GammaCorrector<T>
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
//! Abstractions for working with individually-addressible LED light strands, such as WS2811 lights.
|
||||
//!
|
||||
//! An output driver implements the [Lights] trait, which you feed pixel values of a compatible type.
|
||||
//! The [rgb] module contains some basic color-manipulation tools, and the [gamma] module supports
|
||||
//! converting perceptual to physical color space for output.
|
||||
#![no_std]
|
||||
|
||||
pub mod gamma;
|
||||
|
@ -11,14 +16,28 @@ use core::borrow::Borrow;
|
|||
#[derive(Clone, Copy)]
|
||||
pub struct HardwareRgb(pub u8, pub u8, pub u8);
|
||||
|
||||
/// Represents a string of lights which can be individually updated in linear order.
|
||||
pub trait Lights {
|
||||
/// The type of value each light in the strand can take.
|
||||
///
|
||||
/// Probably either a [rgb::Rgb] (pre-gamma correction) or [HardwareRgb] (post-gamma correction),
|
||||
/// but in theory monochrome LEDs might take a numeric type, or bools for a strand without even brightness control.
|
||||
type Pixel;
|
||||
|
||||
/// Send a pixel value to the next light in the string.
|
||||
///
|
||||
/// Updating a string is likely a time-sensitive operation, so aim to keep this in a tight loop.
|
||||
/// (WS2811 and similar lighting will latch after the data line is quiet long enough)
|
||||
fn render(&mut self, pixel: &Self::Pixel);
|
||||
|
||||
/// Indicate that all pixels have been updated, and the next render() should start at the beginning again.
|
||||
fn latch(&mut self);
|
||||
}
|
||||
|
||||
/// Extension trait to fluently dump an iterator of pixels into a light strand.
|
||||
pub trait PixelIterator<T: Lights> {
|
||||
/// Display all pixel from this iterator onto the given strand.
|
||||
/// Does *not* call [Lights::latch].
|
||||
fn render_to(&mut self, lights: &mut T);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,11 +46,16 @@ impl core::ops::Mul<u8> for Rgb
|
|||
}
|
||||
}
|
||||
|
||||
/// Construct an [Rgb] from a monochrome value.
|
||||
#[inline]
|
||||
pub fn gray(gray: u8) -> Rgb {
|
||||
Rgb(gray, gray, gray)
|
||||
}
|
||||
|
||||
/// Interpolate linearly between two colors.
|
||||
///
|
||||
/// The "mix" value is RGB to permit blending channels individually,
|
||||
/// but most often you will probably use [gray] to generate the mix value.
|
||||
#[inline]
|
||||
pub fn blend(a: Rgb, b: Rgb, mix: Rgb) -> Rgb {
|
||||
(a * Rgb(255 - mix.0, 255 - mix.1, 255 - mix.2)) + (b * mix)
|
||||
|
|
Loading…
Reference in a new issue