-
Notifications
You must be signed in to change notification settings - Fork 0
/
sol.cpp
115 lines (99 loc) · 3.34 KB
/
sol.cpp
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
107
108
109
110
111
112
113
114
115
/**
* Copyright 2011-2015 Denis Kasak <dkasak[at]termina.org.uk>
*
* This file is part of Sol.
*
* Sol is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Sol is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Sol. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Box.h"
#include "Constants.h"
#include "Camera.h"
#include "ColourRGB.h"
#include "Debug.h"
#include "Film.h"
#include "Light.h"
#include "Material.h"
#include "Plane.h"
#include "Ray.h"
#include "World.h"
#include "Sampler.h"
#include "Screen.h"
#include "Shape.h"
#include "Sphere.h"
#include "Options.h"
#include <cassert>
#include <cstring>
#include <cstdlib>
#include <random>
extern "C" {
#include "dbmp.h"
}
using namespace Sol;
#include "worlds/four_boxes.cpp"
void output_image(const Film& film, size_t width, size_t height, const char* filename) {
DEBUG(1, "Writing BMP...");
unsigned char* image = film.BGR24();
write_bmp(image, width, height, filename);
delete[] image;
}
int
main(int argc, char **argv) {
Options opt;
try {
opt = parse_options(argc, argv);
} catch (const InvalidOption &e) {
std::cout << "Invalid option: " << e.name << std::endl;
exit(EXIT_SUCCESS);
} catch (const InvalidOptionValue &e) {
std::cout << "Invalid value \"" << e.value
<< "\" for option " << e.name << std::endl;
exit(EXIT_SUCCESS);
} catch (const MissingOptionValue &e) {
std::cout << "Missing argument for option " << e.name
<< std::endl;
exit(EXIT_SUCCESS);
}
debug_level = opt.debug_level;
Sampler* sampler;
if (opt.sampler == STOCHASTIC) {
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_real_distribution<double> distribution(0, 1);
auto generator = [rng, distribution] () mutable { return distribution(rng); };
sampler = new StochasticSampler(opt.supersamples, generator);
} else if (opt.sampler == JITTERED) {
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_real_distribution<double> distribution(0, 1);
auto generator = [rng, distribution] () mutable { return distribution(rng); };
sampler = new JitteredSampler(opt.supersamples, generator);
} else /* default to REGULAR sampler */ {
sampler = new RegularSampler(opt.supersamples);
}
Screen screen = Screen(opt.hres, opt.vres);
screen.set_pixel_size(opt.pixel_size);
Camera* camera = create_camera();
camera->set_sampler(sampler);
camera->set_screen(screen);
World* world = build_world();
DEBUG(1, "Began rendering");
camera->render(world);
DEBUG(1, "Finished rendering");
assert(camera->film.size() ==
screen.get_hres() * screen.get_vres());
output_image(camera->film, screen.get_hres(),
screen.get_vres(), opt.output_filename.c_str());
delete world;
return EXIT_SUCCESS;
}