-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcolor.h
106 lines (74 loc) · 3.14 KB
/
color.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#ifndef COLOR_H
#define COLOR_H
#include <ostream>
#include <cassert>
#include "logger.h"
#include "interval.h"
#include "random.h"
class Color {
public:
double r;
double g;
double b;
Color();
Color(double red, double green, double blue);
Color operator+(Color const & right) const;
Color operator-(Color const & right) const;
Color operator*(double const constant) const;
Color operator*(Color const & right) const;
Color operator/(double const constant) const;
static Color random();
static Color random(double min, double max);
};
Color operator*(double left, Color const & right);
std::ostream & operator<<(std::ostream & out, Color const & c);
void write_color(std::ostream & output, Color const & c);
// ------
Color::Color() : r(0), g(0), b(0) { }
Color::Color(double red, double green, double blue) : r(red), g(green), b(blue) { }
Color Color::operator+(Color const & right) const {
return Color(this->r + right.r, this->g + right.g, this->b + right.b);
}
Color Color::operator-(Color const & right) const {
return Color(this->r - right.r, this->g - right.g, this->b - right.b);
}
Color Color::operator*(double const constant) const {
return Color(constant * this->r, constant * this->g, constant * this->b);
}
Color Color::operator*(Color const & right) const {
return Color(this->r * right.r, this->g * right.g, this->b * right.b);
}
Color Color::operator/(double const constant) const {
return Color(this->r / constant, this->g / constant, this->b / constant);
}
Color Color::random() {
return Color(random_double(), random_double(), random_double());
}
Color Color::random(double min, double max) {
return Color(random_double(min, max), random_double(min, max), random_double(min, max));
}
// specific overload for when constant is on the left hand side of the operator
// so technically this is an overload for double
Color operator*(double left, Color const & right) {
return right * left;
}
std::ostream & operator<<(std::ostream & out, Color const & c) {
return out << c.r << " " << c.g << " " << c.b;
}
void write_color(std::ostream & output, Color const & c) {
auto intensityLimit = Interval(0.000000, 0.999999);
// don't want to actually get 256 as a color value, we want to stop at 255
// as for the sqrt, that's "gamma correction". The color we receive into this function
// is in "linear space", whereas most image viewing programs expect color to be in "gamma space",
// where the spacing between color values is not even. Doing the sqrt of a color value converts
// our colors to "gamma 2" space. See https://docs.unity3d.com/Manual/LinearLighting.html for more info.
int R = static_cast<int>(intensityLimit.clamp(sqrt(c.r)) * 256);
int G = static_cast<int>(intensityLimit.clamp(sqrt(c.g)) * 256);
int B = static_cast<int>(intensityLimit.clamp(sqrt(c.b)) * 256);
LOG(
std::clog << "Raw color: " << c.r << " " << c.g << " " << c.b << "\n";
std::clog << "Actual color: " << R << " " << G << " " << B << "\n";
)
output << R << " " << G << " " << B << "\n";
}
#endif