summaryrefslogtreecommitdiff
path: root/src/util/color.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/color.h')
-rw-r--r--src/util/color.h168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/util/color.h b/src/util/color.h
new file mode 100644
index 0000000..526cddc
--- /dev/null
+++ b/src/util/color.h
@@ -0,0 +1,168 @@
+#pragma once
+#include "typedef.h"
+#include <math.h>
+
+struct CLR {
+ F32 r, g, b, a;
+
+ static const CLR WHITE( F32 a_ = 1.f ) { return { 1.f, 1.f, 1.f, a_ }; }
+ static const CLR BLACK( F32 a_ = 1.f ) { return { 0.f, 0.f, 0.f, a_ }; }
+ static const CLR RED( F32 a_ = 1.f ) { return { 1.f, 0.f, 0.f, a_ }; }
+ static const CLR GREEN( F32 a_ = 1.f ) { return { 0.f, 1.f, 0.f, a_ }; }
+ static const CLR BLUE( F32 a_ = 1.f ) { return { 0.f, 0.f, 1.f, a_ }; }
+ static const CLR YELLOW( F32 a_ = 1.f ) { return { 1.f, 1.f, 0.f, a_ }; }
+ static const CLR MAGENTA( F32 a_ = 1.f ) { return { 1.f, 0.f, 1.f, a_ }; }
+ static const CLR CYAN( F32 a_ = 1.f ) { return { 0.f, 1.f, 1.f, a_ }; }
+
+ // slow accurate blend, looks prettier but cache maybe if possible
+ static CLR blend( const CLR& c1, const CLR& c2, float t = 0.5f ) {
+ F32 c1r = c1.r * c1.r;
+ F32 c1g = c1.g * c1.g;
+ F32 c1b = c1.b * c1.b;
+ F32 c1a = c1.a * c1.a;
+ F32 c2r = c2.r * c2.r;
+ F32 c2g = c2.g * c2.g;
+ F32 c2b = c2.b * c2.b;
+ F32 c2a = c2.a * c2.a;
+ return {
+ sqrtf( ( c2r * t ) + ( c1r * ( 1.f - t ) ) ),
+ sqrtf( ( c2g * t ) + ( c1g * ( 1.f - t ) ) ),
+ sqrtf( ( c2b * t ) + ( c1b * ( 1.f - t ) ) ),
+ sqrtf( ( c2a * t ) + ( c1a * ( 1.f - t ) ) )
+ };
+ }
+
+ // fast inaccurate blend
+ static CLR blend_root( const CLR& c1, const CLR& c2, float t = 0.5f ) {
+ return {
+ ( c2.r * t ) + ( c1.r * ( 1.f - t ) ),
+ ( c2.g * t ) + ( c1.g * ( 1.f - t ) ),
+ ( c2.b * t ) + ( c1.b * ( 1.f - t ) ),
+ ( c2.a * t ) + ( c1.a * ( 1.f - t ) )
+ };
+ }
+
+ static CLR from_hsb( F32 hue, F32 saturation, F32 brightness ) {
+ CLR c;
+ if( saturation <= 0.0f ) {
+ c.r = c.g = c.b = brightness;
+ return c;
+ }
+
+ I32 h = (I32)( hue * 6 );
+ F32 f = hue * 6 - h;
+ F32 p = brightness * ( 1 - saturation );
+ F32 q = brightness * ( 1 - f * saturation );
+ F32 t = brightness * ( 1 - (1 - f) * saturation );
+
+ switch( h % 6 ) {
+ case 0:
+ c.r = brightness; c.g = t; c.b = p;
+ return c;
+ case 1:
+ c.r = q; c.g = brightness; c.b = p;
+ return c;
+ case 2:
+ c.r = p; c.g = brightness; c.b = t;
+ return c;
+ case 3:
+ c.r = p; c.g = q; c.b = brightness;
+ return c;
+ case 4:
+ c.r = t; c.g = p; c.b = brightness;
+ return c;
+ case 5:
+ c.r = brightness; c.g = p; c.b = q;
+ return c;
+ }
+
+ return c;
+ }
+
+ CLR operator+( const CLR& c2 ) {
+ return { this->r + c2.r, this->g + c2.g, this->b + c2.b, this->a + c2.a };
+ }
+ CLR operator-( const CLR& c2 ) {
+ return { this->r - c2.r, this->g - c2.g, this->b - c2.b, this->a - c2.a };
+ }
+ CLR operator*( const CLR& c2 ) {
+ return { this->r * c2.r, this->g * c2.g, this->b * c2.b, this->a * c2.a };
+ }
+ CLR operator/( const CLR& c2 ) {
+ F32 r = (c2.r != 0.0f) ? this->r / c2.r : 0.0f;
+ F32 g = (c2.g != 0.0f) ? this->g / c2.g : 0.0f;
+ F32 b = (c2.b != 0.0f) ? this->b / c2.b : 0.0f;
+ F32 a = (c2.a != 0.0f) ? this->a / c2.a : 0.0f;
+
+ return { r, g, b, a };
+ }
+
+ CLR& operator+=( const CLR& c2 ) {
+ r += c2.r;
+ g += c2.g;
+ b += c2.b;
+ a += c2.a;
+ return *this;
+ }
+
+ CLR& operator-=( const CLR& c2 ) {
+ r -= c2.r;
+ g -= c2.g;
+ b -= c2.b;
+ a -= c2.a;
+ return *this;
+ }
+
+ CLR& operator*=( const CLR& c2 ) {
+ r *= c2.r;
+ g *= c2.g;
+ b *= c2.b;
+ a *= c2.a;
+ return *this;
+ }
+
+ CLR& operator/=( const CLR& c2 ) {
+ if( c2.r != 0.0f ) { r /= c2.r; }
+ else { r = 0.0f; }
+
+ if( c2.g != 0.0f ) { g /= c2.g; }
+ else { g = 0.0f; }
+
+ if( c2.b != 0.0f ) { b /= c2.b; }
+ else { b = 0.0f; }
+
+ if( c2.a != 0.0f ) { a /= c2.a; }
+ else { a = 0.0f; }
+
+ return *this;
+ }
+
+ CLR operator*( F32 f ) {
+ return { r * f, g * f, b * f, a * f };
+ }
+
+ CLR operator/( F32 f ) {
+ if( f != 0.0f )
+ return { this->r / f, this->g / f, this->b / f, this->a / f };
+ else
+ return { 0.0f, 0.0f, 0.0f, 0.0f };
+ }
+
+ CLR& operator*=( F32 f ) {
+ r *= f; g *= f; b *= f;
+ return *this;
+ }
+
+ CLR& operator/=( F32 f ) {
+ if( f != 0.0f ) {
+ r /= f;
+ g /= f;
+ b /= f;
+ }
+ else {
+ r = g = b = a = 0.f;
+ }
+
+ return *this;
+ }
+};