store color in linear
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
#![allow(clippy::multiple_bound_locations)]
|
#![allow(clippy::multiple_bound_locations)]
|
||||||
|
|
||||||
|
/// stored in linear for sane manipulation
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, bytemuck::Zeroable, Debug)]
|
#[derive(Clone, Copy, bytemuck::Zeroable, Debug)]
|
||||||
pub struct Color<T: ColorNum> {
|
pub struct Color<T: ColorNum> {
|
||||||
@@ -63,6 +64,7 @@ impl ColorNum for f32 {
|
|||||||
|
|
||||||
unsafe impl bytemuck::Pod for Color<u8> {}
|
unsafe impl bytemuck::Pod for Color<u8> {}
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
pub trait F32Conversion {
|
pub trait F32Conversion {
|
||||||
fn to(self) -> f32;
|
fn to(self) -> f32;
|
||||||
fn from(x: f32) -> Self;
|
fn from(x: f32) -> Self;
|
||||||
@@ -87,9 +89,27 @@ impl<T: ColorNum + F32Conversion> Color<T> {
|
|||||||
a: self.a,
|
a: self.a,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn srgb(r: T, g: T, b: T) -> Self {
|
||||||
|
Self {
|
||||||
|
r: s_to_l(r),
|
||||||
|
g: s_to_l(g),
|
||||||
|
b: s_to_l(b),
|
||||||
|
a: T::MAX,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl F32Conversion for f32 {
|
fn s_to_l<T: F32Conversion>(x: T) -> T {
|
||||||
|
let x = x.to();
|
||||||
|
T::from(if x <= 0.0405 {
|
||||||
|
x / 12.92
|
||||||
|
} else {
|
||||||
|
((x + 0.055) / 1.055).powf(2.4)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
impl const F32Conversion for f32 {
|
||||||
fn to(self) -> f32 {
|
fn to(self) -> f32 {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -98,7 +118,7 @@ impl F32Conversion for f32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl F32Conversion for u8 {
|
impl const F32Conversion for u8 {
|
||||||
fn to(self) -> f32 {
|
fn to(self) -> f32 {
|
||||||
self as f32 / 255.0
|
self as f32 / 255.0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ fn draw_texture(region: Region, info: TextureInfo) -> vec4<f32> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw_rounded_rect(region: Region, rect: Rect) -> vec4<f32> {
|
fn draw_rounded_rect(region: Region, rect: Rect) -> vec4<f32> {
|
||||||
var color = read_color(rect.color);
|
var color = unpack4x8unorm(rect.color);
|
||||||
|
|
||||||
let edge = 0.5;
|
let edge = 0.5;
|
||||||
|
|
||||||
@@ -133,20 +133,3 @@ fn distance_from_rect(pixel_pos: vec2<f32>, rect_center: vec2<f32>, rect_corner:
|
|||||||
return length(max(q, vec2(0.0))) - radius;
|
return length(max(q, vec2(0.0))) - radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_color(c: u32) -> vec4<f32> {
|
|
||||||
let color = unpack4x8unorm(c);
|
|
||||||
return vec4(
|
|
||||||
srgb_to_linear(color.r),
|
|
||||||
srgb_to_linear(color.g),
|
|
||||||
srgb_to_linear(color.b),
|
|
||||||
color.a,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn srgb_to_linear(c: f32) -> f32 {
|
|
||||||
if c <= 0.04045 {
|
|
||||||
return c / 12.92;
|
|
||||||
} else {
|
|
||||||
return pow((c + 0.055) / 1.055, 2.4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -157,10 +157,10 @@ impl Client {
|
|||||||
let rect = rect(color)
|
let rect = rect(color)
|
||||||
.id_on(Sense::click(), move |id, ctx: &mut Client, _| {
|
.id_on(Sense::click(), move |id, ctx: &mut Client, _| {
|
||||||
ctx.ui[main].inner.set_static(to);
|
ctx.ui[main].inner.set_static(to);
|
||||||
ctx.ui[id].color = color.add_rgb(-0.2);
|
ctx.ui[id].color = color.mul_rgb(0.7);
|
||||||
})
|
})
|
||||||
.edit_on(Sense::HoverStart | Sense::unclick(), move |r, _| {
|
.edit_on(Sense::HoverStart | Sense::unclick(), move |r, _| {
|
||||||
r.color = color.add_rgb(0.4);
|
r.color = color.add_rgb(0.2);
|
||||||
})
|
})
|
||||||
.edit_on(Sense::HoverEnd, move |r, _| {
|
.edit_on(Sense::HoverEnd, move |r, _| {
|
||||||
r.color = color;
|
r.color = color;
|
||||||
|
|||||||
Reference in New Issue
Block a user