naev 0.11.5
colour.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
11#include <math.h>
12
13#include "naev.h"
16#include "colour.h"
17
18#include "log.h"
19#include "nmath.h"
20#include "nstring.h"
21
22/*
23 * http://en.wikipedia.org/wiki/SRGB#The_forward_transformation_.28CIE_xyY_or_CIE_XYZ_to_sRGB.29
24 */
25__attribute__((const)) double linearToGamma( double x )
26{
27 if (x <= 0.0031308)
28 return x * 12.92;
29 return 1.055 * pow(x, 1.0 / 2.4) - 0.055;
30}
31/*
32 * http://en.wikipedia.org/wiki/SRGB#The_reverse_transformation
33 */
34__attribute__((const)) double gammaToLinear( double x )
35{
36 if (x <= 0.04045)
37 return x / 12.92;
38 return pow((x + 0.055) / 1.055, 2.4);
39}
40
41void col_linearToGamma( glColour *c )
42{
43 c->r = linearToGamma( c->r );
44 c->g = linearToGamma( c->g );
45 c->b = linearToGamma( c->b );
46}
47
48void col_gammaToLinear( glColour *c )
49{
50 c->r = gammaToLinear( c->r );
51 c->g = gammaToLinear( c->g );
52 c->b = gammaToLinear( c->b );
53}
54
65void col_hsv2rgb( glColour *c, float h, float s, float v )
66{
67 float var_h, var_i, var_1, var_2, var_3;
68
69 if (v > 1)
70 v = 1;
71
72 if (s == 0) {
73 c->r = v;
74 c->g = v;
75 c->b = v;
76 }
77 else {
78 var_h = h * 6 / 360.;
79 var_i = floor(var_h);
80 var_1 = v * (1 - s);
81 var_2 = v * (1 - s * (var_h - var_i));
82 var_3 = v * (1 - s * (1 - (var_h - var_i)));
83
84 if (var_i == 0) { c->r = v ; c->g = var_3 ; c->b = var_1; }
85 else if (var_i == 1) { c->r = var_2 ; c->g = v ; c->b = var_1; }
86 else if (var_i == 2) { c->r = var_1 ; c->g = v ; c->b = var_3; }
87 else if (var_i == 3) { c->r = var_1 ; c->g = var_2 ; c->b = v; }
88 else if (var_i == 4) { c->r = var_3 ; c->g = var_1 ; c->b = v; }
89 else { c->r = v ; c->g = var_1 ; c->b = var_2; }
90 }
91
92 c->r = gammaToLinear( c->r );
93 c->g = gammaToLinear( c->g );
94 c->b = gammaToLinear( c->b );
95}
96
111void col_rgb2hsv( float *H, float *S, float *V, float R, float G, float B )
112{
113 float H1, S1, V1;
114#ifdef HSV_TRAVIS
115 float R1, G1, B1;
116#endif /* HSV_TRAVIS */
117 float max, min, diff;
118
119 R = gammaToLinear( R );
120 G = gammaToLinear( G );
121 B = gammaToLinear( B );
122
123 max = max3( R, G, B );
124 min = min3( R, G, B );
125 diff = max - min;
126
127 if (max == 0)
128 H1 = S1 = V1 = 0;
129 else {
130 V1 = max;
131 S1 = diff/max;
132 if (S1 == 0)
133 /* H1 is undefined, but give it a value anyway */
134 H1 = 0;
135 else {
136#ifdef HSV_TRAVIS
137 R1 = (max - R)/diff;
138 G1 = (max - G)/diff;
139 B1 = (max - B)/diff;
140
141 if ((R == max) && (G == min))
142 H1 = 5 + B1;
143 else {
144 if ((R == max) && (G != min))
145 H1 = 1 - G1;
146 else {
147 if ((G == max) && (B == min))
148 H1 = 1 + R1;
149 else {
150 if ((G == max) && (B != min))
151 H1 = 3 - B1;
152 else {
153 if (R == max)
154 H1 = 3 + G1;
155 else
156 H1 = 5 - R1;
157 }
158 }
159 }
160 }
161
162 H1 *= 60; /* convert to range [0, 360] degrees */
163#else /* HSV_TRAVIS */
164 H1 = 0.; /* Shuts up Clang. */
165 /* assume Foley & VanDam HSV */
166 if (R == max)
167 H1 = (G - B)/diff;
168 if (G == max)
169 H1 = 2 + (B - R)/diff;
170 if (B == max)
171 H1 = 4 + (R - G)/diff;
172
173 H1 *= 60; /* convert to range [0, 360] degrees */
174 if (H1 < 0)
175 H1 += 360;
176#endif /* HSV_TRAVIS */
177 }
178 }
179 *H = H1;
180 *S = S1;
181 *V = V1;
182}
183
192void col_blend( glColour *blend, const glColour *fg, const glColour *bg, float alpha )
193{
194 blend->r = (1. - alpha) * bg->r + alpha * fg->r;
195 blend->g = (1. - alpha) * bg->g + alpha * fg->g;
196 blend->b = (1. - alpha) * bg->b + alpha * fg->b;
197 blend->a = (1. - alpha) * bg->a + alpha * fg->a;
198}
void col_blend(glColour *blend, const glColour *fg, const glColour *bg, float alpha)
Blends two colours.
Definition colour.c:192
void col_rgb2hsv(float *H, float *S, float *V, float R, float G, float B)
Changes colour space from RGB to HSV.
Definition colour.c:111
void col_hsv2rgb(glColour *c, float h, float s, float v)
Changes colour space from HSV to RGB.
Definition colour.c:65
Header file with generic functions and naev-specifics.
double min3(double v1, double v2, double v3)
Returns the minimum of 3 values.
Definition nmath.c:56
double max3(double v1, double v2, double v3)
Returns the maximum of 3 values.
Definition nmath.c:46
static const double c[]
Definition rng.c:264