add HSV support and convertion helper functions
This commit is contained in:
parent
60cc86ec41
commit
a06c109665
2 changed files with 131 additions and 13 deletions
|
@ -14,19 +14,6 @@ typedef union {
|
|||
};
|
||||
} PtkRGB;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
float h;
|
||||
float s;
|
||||
float v;
|
||||
};
|
||||
struct {
|
||||
float hue;
|
||||
float saturation;
|
||||
float value;
|
||||
};
|
||||
} PtkHSV;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
float r;
|
||||
|
@ -42,6 +29,20 @@ typedef union {
|
|||
};
|
||||
} PtkRGBA;
|
||||
|
||||
// all values in range [0.0, 360.0]
|
||||
typedef union {
|
||||
struct {
|
||||
float h;
|
||||
float s;
|
||||
float v;
|
||||
};
|
||||
struct {
|
||||
float hue;
|
||||
float saturation;
|
||||
float value;
|
||||
};
|
||||
} PtkHSV;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
float h;
|
||||
|
@ -57,4 +58,10 @@ typedef union {
|
|||
};
|
||||
} PtkHSVA;
|
||||
|
||||
PtkHSV ptk_rgb_to_hsv(const PtkRGB rgb);
|
||||
PtkRGB ptk_hsv_to_rgb(const PtkHSV hsv);
|
||||
|
||||
PtkHSVA ptk_rgba_to_hsva(const PtkRGBA rgba);
|
||||
PtkRGBA ptk_hsva_to_rgba(const PtkHSVA hsva);
|
||||
|
||||
#endif // PTK_PTK_COLOR_H_
|
||||
|
|
111
src/ptk_color.c
Normal file
111
src/ptk_color.c
Normal file
|
@ -0,0 +1,111 @@
|
|||
#include <ptk_color.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
// https://github.com/raysan5/raylib/blob/65c40035/src/rtextures.c#L4933
|
||||
PtkHSV ptk_rgb_to_hsv(const PtkRGB rgb) {
|
||||
PtkHSV hsv = {0};
|
||||
|
||||
float min, max;
|
||||
|
||||
min = rgb.r < rgb.g ? rgb.r : rgb.g;
|
||||
min = min < rgb.b ? min : rgb.b;
|
||||
|
||||
max = rgb.r > rgb.g ? rgb.r : rgb.g;
|
||||
max = max > rgb.b ? max : rgb.b;
|
||||
|
||||
hsv.v = max;
|
||||
const float delta = max - min;
|
||||
|
||||
if (delta < 0.00001f) {
|
||||
hsv.s = 0.0f;
|
||||
hsv.h = 0.0f;
|
||||
return hsv;
|
||||
}
|
||||
|
||||
if (max > 0.0f) {
|
||||
hsv.s = delta / max;
|
||||
} else {
|
||||
hsv.s = 0.0f;
|
||||
hsv.h = NAN;
|
||||
}
|
||||
|
||||
if (rgb.r >= max) {
|
||||
hsv.h = (rgb.g - rgb.b) / delta;
|
||||
} else {
|
||||
if (rgb.g >= max) {
|
||||
hsv.h = 2.0f + (rgb.b - rgb.r) / delta;
|
||||
} else {
|
||||
hsv.h = 4.0f + (rgb.r - rgb.g) / delta;
|
||||
}
|
||||
}
|
||||
|
||||
hsv.h *= 60.0f;
|
||||
|
||||
if (hsv.h < 0.0f) {
|
||||
hsv.h += 360.0f;
|
||||
}
|
||||
|
||||
return hsv;
|
||||
}
|
||||
|
||||
// https://github.com/raysan5/raylib/blob/65c40035/src/rtextures.c#L4988
|
||||
PtkRGB ptk_hsv_to_rgb(const PtkHSV hsv) {
|
||||
PtkRGB rgb = {0};
|
||||
|
||||
const float s = hsv.s / 360.0f;
|
||||
const float v = hsv.v / 360.0f;
|
||||
|
||||
float k = fmodf(5.0f + hsv.h / 60.0f, 6);
|
||||
float t = 4.0f - k;
|
||||
k = t < k ? t : k;
|
||||
k = k < 1 ? k : 1;
|
||||
k = k > 0 ? k : 0;
|
||||
rgb.r = v - v * s * k;
|
||||
|
||||
k = fmodf(3.0f + hsv.h / 60.0f, 6);
|
||||
t = 4.0f - k;
|
||||
k = t < k ? t : k;
|
||||
k = k < 1 ? k : 1;
|
||||
k = k > 0 ? k : 0;
|
||||
rgb.g = v - v * s * k;
|
||||
|
||||
k = fmodf(1.0f + hsv.h / 60.0f, 6);
|
||||
t = 4.0f - k;
|
||||
k = t < k ? t : k;
|
||||
k = k < 1 ? k : 1;
|
||||
k = k > 0 ? k : 0;
|
||||
rgb.b = v - v * s * k;
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
PtkHSVA ptk_rgba_to_hsva(const PtkRGBA rgba) {
|
||||
PtkHSV hsv = ptk_rgb_to_hsv((PtkRGB){
|
||||
.r = rgba.r,
|
||||
.g = rgba.g,
|
||||
.b = rgba.b
|
||||
});
|
||||
|
||||
return (PtkHSVA){
|
||||
.h = hsv.h,
|
||||
.s = hsv.s,
|
||||
.v = hsv.v,
|
||||
.a = rgba.a * 360.0f,
|
||||
};
|
||||
}
|
||||
|
||||
PtkRGBA ptk_hsva_to_rgba(const PtkHSVA hsva) {
|
||||
PtkRGB rgb = ptk_hsv_to_rgb((PtkHSV){
|
||||
.h = hsva.h,
|
||||
.s = hsva.s,
|
||||
.v = hsva.v,
|
||||
});
|
||||
|
||||
return (PtkRGBA){
|
||||
.r = rgb.r,
|
||||
.g = rgb.g,
|
||||
.b = rgb.b,
|
||||
.a = hsva.a / 360.0f,
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue