-
Notifications
You must be signed in to change notification settings - Fork 0
/
texture.h
89 lines (68 loc) · 2.53 KB
/
texture.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
#ifndef TEXTURE_H
#define TEXTURE_H
#include "rtweekend.h"
#include "rtw_stb_image.h"
class texture {
public:
virtual ~texture() = default;
virtual color value(double u, double v, const point3& p) const = 0;
};
class solid_color : public texture {
public:
solid_color(color c) : color_value(c) {}
solid_color(double red, double green, double blue) : solid_color(color(red,green,blue)) {}
color value(double u, double v, const point3& p) const override {
return color_value;
}
private:
color color_value;;
};
class checker_texture : public texture {
public:
checker_texture(double _scale, shared_ptr<texture> _even, shared_ptr<texture> _odd)
: inv_scale(1.0 / _scale), even(_even), odd(_odd) {}
checker_texture(double _scale, color c1, color c2)
: inv_scale(1.0 / _scale),
even(make_shared<solid_color>(c1)),
odd(make_shared<solid_color>(c2))
{}
color value(double u, double v, const point3& p) const override {
auto xInteger = static_cast<int>(std::floor(inv_scale * p.x()));
auto yInteger = static_cast<int>(std::floor(inv_scale * p.y()));
auto zInteger = static_cast<int>(std::floor(inv_scale * p.z()));
bool isEven = (xInteger + yInteger + zInteger) % 2 == 0;
return isEven ? even->value(u, v, p) : odd->value(u, v, p);
}
private:
double inv_scale;
shared_ptr<texture> even;
shared_ptr<texture> odd;
};
class image_texture : public texture {
public:
std::string path;
image_texture(const char* filename) : image(filename) {
path = filename;
}
image_texture(const image_texture&) = delete;
image_texture& operator=(const image_texture&) = delete;
image_texture(image_texture&& other) noexcept : image(std::move(other.image)) {}
image_texture& operator=(image_texture&& other) noexcept {
std::swap(image, other.image);
}
color value(double u, double v, const point3& p) const override {
// If we have no texture data, then return solid cyan as a debugging aid.
if (image.height() <= 0) return color(0,1,1);
// Camp input texture coordinates to [0,1] x [1,0]
u = interval(0,1).clamp(u);
v = 1.0 - interval(0,1).clamp(v); // Flip V to image coordinates
auto i = static_cast<int>(u * image.width());
auto j = static_cast<int>(v * image.height());
auto pixel = image.pixel_data(i,j);
auto color_scale = 1.0 / 255.0;
return color(color_scale*pixel[0], color_scale*pixel[1], color_scale*pixel[2]);
}
private:
rtw_image image;
};
#endif