color.rs
1 /// A struct that represents a color to use on objects, the clear color or labels. 2 use glam::{Vec3, Vec4, vec3, vec4}; 3 use let_engine_macros::Vertex; 4 5 /// Representation of a color in form of 4 `f32`'s for R, G, B and A. 6 #[derive(Default, Clone, Copy, Debug, PartialEq, bytemuck::AnyBitPattern, Vertex)] 7 #[repr(C)] 8 pub struct Color { 9 #[format(Rgba32Float)] 10 rgba: [f32; 4], 11 } 12 13 /// Declaration 14 impl Color { 15 /// Full white color 16 pub const WHITE: Self = Self::from_rgb(1.0, 1.0, 1.0); 17 18 /// Black color with full alpha channel 19 pub const BLACK: Self = Self::from_r(0.0); 20 21 /// Full Black transparent color 22 pub const TRANSPARENT: Self = Self::from_rgba(0.0, 0.0, 0.0, 0.0); 23 24 /// Opaque red color 25 pub const RED: Self = Self::from_r(1.0); 26 27 /// Opaque green color 28 pub const GREEN: Self = Self::from_g(1.0); 29 30 /// Opaque blue color 31 pub const BLUE: Self = Self::from_b(1.0); 32 33 /// Makes a color from red, green, blue and alpha. 34 #[inline] 35 pub const fn from_rgba(red: f32, green: f32, blue: f32, alpha: f32) -> Self { 36 Self { 37 rgba: [red, green, blue, alpha], 38 } 39 } 40 /// Makes a color from red, green and blue. 41 #[inline] 42 pub const fn from_rgb(red: f32, green: f32, blue: f32) -> Self { 43 Self { 44 rgba: [red, green, blue, 1.0], 45 } 46 } 47 /// Makes a color from red and green. 48 #[inline] 49 pub const fn from_rg(red: f32, green: f32) -> Self { 50 Self { 51 rgba: [red, green, 0.0, 1.0], 52 } 53 } 54 /// Makes a color from red and blue. 55 #[inline] 56 pub const fn from_rb(red: f32, blue: f32) -> Self { 57 Self { 58 rgba: [red, 0.0, blue, 1.0], 59 } 60 } 61 /// Makes a color from red. 62 #[inline] 63 pub const fn from_r(red: f32) -> Self { 64 Self { 65 rgba: [red, 0.0, 0.0, 1.0], 66 } 67 } 68 /// Makes a color from green and blue. 69 #[inline] 70 pub const fn from_gb(green: f32, blue: f32) -> Self { 71 Self { 72 rgba: [0.0, green, blue, 1.0], 73 } 74 } 75 /// Makes a color from green. 76 #[inline] 77 pub const fn from_g(green: f32) -> Self { 78 Self { 79 rgba: [0.0, green, 0.0, 1.0], 80 } 81 } 82 /// Makes a color from blue. 83 #[inline] 84 pub const fn from_b(blue: f32) -> Self { 85 Self { 86 rgba: [0.0, 0.0, blue, 1.0], 87 } 88 } 89 } 90 91 /// Usage 92 impl Color { 93 /// Returns the red green blue and alpha of this color. 94 #[inline] 95 pub fn rgba(&self) -> [f32; 4] { 96 self.rgba 97 } 98 99 /// Returns the red green and blue of this color. 100 #[inline] 101 pub fn rgb(&self) -> [f32; 3] { 102 [self.rgba[0], self.rgba[1], self.rgba[2]] 103 } 104 105 /// Returns the red of this color. 106 #[inline] 107 pub fn r(&self) -> f32 { 108 self.rgba[0] 109 } 110 111 /// Returns the green of this color. 112 #[inline] 113 pub fn g(&self) -> f32 { 114 self.rgba[1] 115 } 116 117 /// Returns the blue of this color. 118 #[inline] 119 pub fn b(&self) -> f32 { 120 self.rgba[2] 121 } 122 123 /// Returns the alpha or transparency of this color. 124 #[inline] 125 pub fn alpha(&self) -> f32 { 126 self.rgba[3] 127 } 128 129 /// Sets the red channel of this color. 130 #[inline] 131 pub fn set_r(&mut self, red: f32) { 132 self.rgba[0] = red; 133 } 134 135 /// Sets the green channel of this color. 136 #[inline] 137 pub fn set_g(&mut self, green: f32) { 138 self.rgba[1] = green; 139 } 140 141 /// Sets the blue channel of this color. 142 #[inline] 143 pub fn set_b(&mut self, blue: f32) { 144 self.rgba[2] = blue; 145 } 146 147 /// Sets the alpha channel of this color. 148 #[inline] 149 pub fn set_a(&mut self, alpha: f32) { 150 self.rgba[3] = alpha; 151 } 152 153 /// Interpolates to the next color. 154 #[inline] 155 pub fn lerp(self, value: Self, s: f32) -> Self { 156 self * (1.0 - s) + value * s 157 } 158 } 159 160 impl Color { 161 /// Returns `true` if this color is transparent, meaning the alpha value is not `1.0` or above. 162 #[inline] 163 pub fn is_transparent(&self) -> bool { 164 self.alpha() < 1.0 165 } 166 } 167 168 impl From<[f32; 4]> for Color { 169 #[inline] 170 fn from(value: [f32; 4]) -> Self { 171 Color::from_rgba(value[0], value[1], value[2], value[3]) 172 } 173 } 174 impl From<Vec4> for Color { 175 #[inline] 176 fn from(value: Vec4) -> Self { 177 Color::from_rgba(value.x, value.y, value.z, value.w) 178 } 179 } 180 impl From<[f32; 3]> for Color { 181 #[inline] 182 fn from(value: [f32; 3]) -> Self { 183 Color::from_rgb(value[0], value[1], value[2]) 184 } 185 } 186 impl From<Vec3> for Color { 187 #[inline] 188 fn from(value: Vec3) -> Self { 189 Color::from_rgb(value.x, value.y, value.z) 190 } 191 } 192 impl From<f32> for Color { 193 #[inline] 194 fn from(value: f32) -> Self { 195 Color::from_r(value) 196 } 197 } 198 impl From<Color> for f32 { 199 #[inline] 200 fn from(value: Color) -> f32 { 201 value.r() 202 } 203 } 204 impl From<Color> for [f32; 3] { 205 #[inline] 206 fn from(value: Color) -> [f32; 3] { 207 value.rgb() 208 } 209 } 210 impl From<Color> for [f32; 4] { 211 #[inline] 212 fn from(value: Color) -> [f32; 4] { 213 value.rgba() 214 } 215 } 216 impl From<Color> for Vec3 { 217 #[inline] 218 fn from(value: Color) -> Vec3 { 219 vec3(value.r(), value.g(), value.b()) 220 } 221 } 222 impl From<Color> for Vec4 { 223 #[inline] 224 fn from(value: Color) -> Vec4 { 225 vec4(value.r(), value.g(), value.b(), value.alpha()) 226 } 227 } 228 impl std::ops::Add<Color> for Color { 229 type Output = Self; 230 #[inline] 231 fn add(self, rhs: Self) -> Self::Output { 232 Self { 233 rgba: [ 234 self.rgba[0] + rhs.rgba[0], 235 self.rgba[1] + rhs.rgba[1], 236 self.rgba[2] + rhs.rgba[2], 237 self.rgba[3] + rhs.rgba[3], 238 ], 239 } 240 } 241 } 242 243 impl std::ops::Sub<Color> for Color { 244 type Output = Self; 245 #[inline] 246 fn sub(self, rhs: Self) -> Self::Output { 247 Self { 248 rgba: [ 249 self.rgba[0] - rhs.rgba[0], 250 self.rgba[1] - rhs.rgba[1], 251 self.rgba[2] - rhs.rgba[2], 252 self.rgba[3] - rhs.rgba[3], 253 ], 254 } 255 } 256 } 257 258 impl std::ops::Mul<Color> for Color { 259 type Output = Self; 260 #[inline] 261 fn mul(self, rhs: Self) -> Self::Output { 262 Self { 263 rgba: [ 264 self.rgba[0] * rhs.rgba[0], 265 self.rgba[1] * rhs.rgba[1], 266 self.rgba[2] * rhs.rgba[2], 267 self.rgba[3] * rhs.rgba[3], 268 ], 269 } 270 } 271 } 272 273 impl std::ops::Div<Color> for Color { 274 type Output = Self; 275 #[inline] 276 fn div(self, rhs: Self) -> Self::Output { 277 Self { 278 rgba: [ 279 self.rgba[0] / rhs.rgba[0], 280 self.rgba[1] / rhs.rgba[1], 281 self.rgba[2] / rhs.rgba[2], 282 self.rgba[3] / rhs.rgba[3], 283 ], 284 } 285 } 286 } 287 288 impl std::ops::Add<f32> for Color { 289 type Output = Self; 290 #[inline] 291 fn add(self, rhs: f32) -> Self::Output { 292 Self { 293 rgba: self.rgba.map(|x| x + rhs), 294 } 295 } 296 } 297 298 impl std::ops::Sub<f32> for Color { 299 type Output = Self; 300 #[inline] 301 fn sub(self, rhs: f32) -> Self::Output { 302 Self { 303 rgba: self.rgba.map(|x| x - rhs), 304 } 305 } 306 } 307 308 impl std::ops::Mul<f32> for Color { 309 type Output = Self; 310 #[inline] 311 fn mul(self, rhs: f32) -> Self::Output { 312 Self { 313 rgba: self.rgba.map(|x| x * rhs), 314 } 315 } 316 } 317 318 impl std::ops::Div<f32> for Color { 319 type Output = Self; 320 #[inline] 321 fn div(self, rhs: f32) -> Self::Output { 322 Self { 323 rgba: self.rgba.map(|x| x / rhs), 324 } 325 } 326 } 327 328 impl std::ops::AddAssign<Color> for Color { 329 #[inline] 330 fn add_assign(&mut self, rhs: Self) { 331 self.rgba[0].add_assign(rhs.rgba[0]); 332 self.rgba[1].add_assign(rhs.rgba[1]); 333 self.rgba[2].add_assign(rhs.rgba[2]); 334 self.rgba[3].add_assign(rhs.rgba[3]); 335 } 336 } 337 338 impl std::ops::SubAssign<Color> for Color { 339 #[inline] 340 fn sub_assign(&mut self, rhs: Self) { 341 self.rgba[0].sub_assign(rhs.rgba[0]); 342 self.rgba[1].sub_assign(rhs.rgba[1]); 343 self.rgba[2].sub_assign(rhs.rgba[2]); 344 self.rgba[3].sub_assign(rhs.rgba[3]); 345 } 346 } 347 348 impl std::ops::MulAssign<Color> for Color { 349 #[inline] 350 fn mul_assign(&mut self, rhs: Self) { 351 self.rgba[0].mul_assign(rhs.rgba[0]); 352 self.rgba[1].mul_assign(rhs.rgba[1]); 353 self.rgba[2].mul_assign(rhs.rgba[2]); 354 self.rgba[3].mul_assign(rhs.rgba[3]); 355 } 356 } 357 358 impl std::ops::DivAssign<Color> for Color { 359 #[inline] 360 fn div_assign(&mut self, rhs: Self) { 361 self.rgba[0].div_assign(rhs.rgba[0]); 362 self.rgba[1].div_assign(rhs.rgba[1]); 363 self.rgba[2].div_assign(rhs.rgba[2]); 364 self.rgba[3].div_assign(rhs.rgba[3]); 365 } 366 } 367 368 impl std::ops::AddAssign<f32> for Color { 369 #[inline] 370 fn add_assign(&mut self, rhs: f32) { 371 for mut x in self.rgba { 372 x.add_assign(rhs) 373 } 374 } 375 } 376 377 impl std::ops::SubAssign<f32> for Color { 378 #[inline] 379 fn sub_assign(&mut self, rhs: f32) { 380 for mut x in self.rgba { 381 x.sub_assign(rhs) 382 } 383 } 384 } 385 386 impl std::ops::MulAssign<f32> for Color { 387 #[inline] 388 fn mul_assign(&mut self, rhs: f32) { 389 for mut x in self.rgba { 390 x.mul_assign(rhs) 391 } 392 } 393 } 394 395 impl std::ops::DivAssign<f32> for Color { 396 #[inline] 397 fn div_assign(&mut self, rhs: f32) { 398 for mut x in self.rgba { 399 x.div_assign(rhs) 400 } 401 } 402 } 403 404 impl std::ops::Deref for Color { 405 type Target = [f32; 4]; 406 407 fn deref(&self) -> &Self::Target { 408 &self.rgba 409 } 410 } 411 412 impl std::ops::DerefMut for Color { 413 fn deref_mut(&mut self) -> &mut Self::Target { 414 &mut self.rgba 415 } 416 }