1818#include " sphere.h"
1919
2020#include < iostream>
21+ #include < thread>
2122
23+ #define STB_IMAGE_WRITE_IMPLEMENTATION
24+ #include " external/stb_image_write.h"
2225
23- color ray_color (const ray& r, const hittable& world, int depth) {
26+
27+ color ray_color (const ray& r, const hittable& world, int depth)
28+ {
2429 hit_record rec;
2530
2631 // If we've exceeded the ray bounce limit, no more light is gathered.
@@ -87,6 +92,44 @@ hittable_list random_scene() {
8792 return world;
8893}
8994
95+ struct SimpleRGB
96+ {
97+ uint8_t r;
98+ uint8_t g;
99+ uint8_t b;
100+ };
101+
102+
103+ void write_simple_color (SimpleRGB& outColor, color pixel_color, int samples_per_pixel)
104+ {
105+ auto r = pixel_color.x ();
106+ auto g = pixel_color.y ();
107+ auto b = pixel_color.z ();
108+
109+ // Replace NaN components with zero. See explanation in Ray Tracing: The Rest of Your Life.
110+ if (r != r) r = 0.0 ;
111+ if (g != g) g = 0.0 ;
112+ if (b != b) b = 0.0 ;
113+
114+ // Divide the color by the number of samples and gamma-correct for gamma=2.0.
115+ auto scale = 1.0 / samples_per_pixel;
116+ r = sqrt (scale * r);
117+ g = sqrt (scale * g);
118+ b = sqrt (scale * b);
119+
120+ outColor.r = static_cast <int >(256 * clamp (r, 0.0 , 0.999 ));
121+ outColor.g = static_cast <int >(256 * clamp (g, 0.0 , 0.999 ));
122+ outColor.b = static_cast <int >(256 * clamp (b, 0.0 , 0.999 ));
123+ }
124+
125+ void Renderer (std::atomic_uint32_t &ScanLine,
126+ int32_t image_height,
127+ int32_t image_width,
128+ int32_t samples_per_pixel,
129+ std::vector< SimpleRGB > &colors)
130+ {
131+
132+ }
90133
91134int main () {
92135
@@ -98,6 +141,9 @@ int main() {
98141 const int samples_per_pixel = 10 ;
99142 const int max_depth = 50 ;
100143
144+ std::vector< SimpleRGB > colors;
145+ colors.resize (image_width * image_height);
146+
101147 // World
102148
103149 auto world = random_scene ();
@@ -113,22 +159,47 @@ int main() {
113159 camera cam (lookfrom, lookat, vup, 20 , aspect_ratio, aperture, dist_to_focus);
114160
115161 // Render
116-
117162 std::cout << " P3\n " << image_width << ' ' << image_height << " \n 255\n " ;
118163
119- for (int j = image_height-1 ; j >= 0 ; --j) {
120- std::cerr << " \r Scanlines remaining: " << j << ' ' << std::flush;
121- for (int i = 0 ; i < image_width; ++i) {
122- color pixel_color (0 ,0 ,0 );
123- for (int s = 0 ; s < samples_per_pixel; ++s) {
124- auto u = (i + random_double ()) / (image_width-1 );
125- auto v = (j + random_double ()) / (image_height-1 );
126- ray r = cam.get_ray (u, v);
127- pixel_color += ray_color (r, world, max_depth);
164+ std::atomic_uint32_t ScanLine = 0 ;
165+
166+ auto runThread = [&]() {
167+ while (true )
168+ {
169+ auto currentLine = ScanLine.fetch_add (1 );
170+ if (currentLine >= image_height)
171+ {
172+ return ;
173+ }
174+ auto actualLine = image_height - currentLine - 1 ;
175+ std::cerr << " \r Scanlines remaining: " << actualLine << std::endl;// << ' ' << std::flush;
176+ for (int i = 0 ; i < image_width; ++i) {
177+ color pixel_color (0 , 0 , 0 );
178+ for (int s = 0 ; s < samples_per_pixel; ++s) {
179+ auto u = (i + random_double ()) / (image_width - 1 );
180+ auto v = (currentLine + random_double ()) / (image_height - 1 );
181+ ray r = cam.get_ray (u, v);
182+ pixel_color += ray_color (r, world, max_depth);
183+ }
184+ uint32_t Idx = (actualLine * image_width) + i;
185+ write_simple_color (colors[Idx], pixel_color, samples_per_pixel);
128186 }
129- write_color (std::cout, pixel_color, samples_per_pixel);
130187 }
131- }
188+ };
189+
190+ const auto threadCount = std::max<uint32_t >( std::thread::hardware_concurrency () - 1 , 2 );
191+
192+ std::vector<std::thread> my_threads{};
193+ my_threads.reserve (threadCount);
194+
195+ for (int i = 0 ; i < threadCount; i++)
196+ my_threads.emplace_back (runThread);
197+
198+ for (auto & thread : my_threads)
199+ if (thread.joinable ())
200+ thread.join ();
201+
202+ stbi_write_bmp (" test.bmp" , image_width, image_height, 3 , colors.data ());
132203
133204 std::cerr << " \n Done.\n " ;
134205}
0 commit comments