fstream is a proper RAII object

master
Dmitry V. Sokolov 2022-03-18 17:33:28 +01:00
parent d379242317
commit ce6b7852b7
1 changed files with 18 additions and 22 deletions

View File

@ -34,19 +34,19 @@ struct Sphere {
Material material; Material material;
}; };
static const Material ivory = {1.0, {0.9, 0.5, 0.1, 0.0}, {0.4, 0.4, 0.3}, 50.}; constexpr Material ivory = {1.0, {0.9, 0.5, 0.1, 0.0}, {0.4, 0.4, 0.3}, 50.};
static const Material glass = {1.5, {0.0, 0.9, 0.1, 0.8}, {0.6, 0.7, 0.8}, 125.}; constexpr Material glass = {1.5, {0.0, 0.9, 0.1, 0.8}, {0.6, 0.7, 0.8}, 125.};
static const Material red_rubber = {1.0, {1.4, 0.3, 0.0, 0.0}, {0.3, 0.1, 0.1}, 10.}; constexpr Material red_rubber = {1.0, {1.4, 0.3, 0.0, 0.0}, {0.3, 0.1, 0.1}, 10.};
static const Material mirror = {1.0, {0.0, 16.0, 0.8, 0.0}, {1.0, 1.0, 1.0}, 1425.}; constexpr Material mirror = {1.0, {0.0, 16.0, 0.8, 0.0}, {1.0, 1.0, 1.0}, 1425.};
static const Sphere spheres[] = { constexpr Sphere spheres[] = {
{{-3, 0, -16}, 2, ivory}, {{-3, 0, -16}, 2, ivory},
{{-1.0, -1.5, -12}, 2, glass}, {{-1.0, -1.5, -12}, 2, glass},
{{ 1.5, -0.5, -18}, 3, red_rubber}, {{ 1.5, -0.5, -18}, 3, red_rubber},
{{ 7, 5, -18}, 4, mirror} {{ 7, 5, -18}, 4, mirror}
}; };
static const vec3 lights[] = { constexpr vec3 lights[] = {
{-20, 20, 20}, {-20, 20, 20},
{ 30, 50, -25}, { 30, 50, -25},
{ 30, 20, 30} { 30, 20, 30}
@ -100,10 +100,10 @@ std::tuple<bool,vec3,vec3,Material> scene_intersect(const vec3 &orig, const vec3
N = (pt - s.center).normalized(); N = (pt - s.center).normalized();
material = s.material; material = s.material;
} }
return {nearest_dist<1000, pt, N, material}; return { nearest_dist<1000, pt, N, material };
} }
vec3 cast_ray(const vec3 &orig, const vec3 &dir, int depth=0) { vec3 cast_ray(const vec3 &orig, const vec3 &dir, const int depth=0) {
auto [hit, point, N, material] = scene_intersect(orig, dir); auto [hit, point, N, material] = scene_intersect(orig, dir);
if (depth>4 || !hit) if (depth>4 || !hit)
return {0.2, 0.7, 0.8}; // background color return {0.2, 0.7, 0.8}; // background color
@ -114,7 +114,7 @@ vec3 cast_ray(const vec3 &orig, const vec3 &dir, int depth=0) {
vec3 refract_color = cast_ray(point, refract_dir, depth + 1); vec3 refract_color = cast_ray(point, refract_dir, depth + 1);
float diffuse_light_intensity = 0, specular_light_intensity = 0; float diffuse_light_intensity = 0, specular_light_intensity = 0;
for (const vec3 light : lights) { // checking if the point lies in the shadow of the light for (const vec3 &light : lights) { // checking if the point lies in the shadow of the light
vec3 light_dir = (light - point).normalized(); vec3 light_dir = (light - point).normalized();
auto [hit, shadow_pt, trashnrm, trashmat] = scene_intersect(point, light_dir); auto [hit, shadow_pt, trashnrm, trashmat] = scene_intersect(point, light_dir);
if (hit && (shadow_pt-point).norm() < (light-point).norm()) continue; if (hit && (shadow_pt-point).norm() < (light-point).norm()) continue;
@ -125,29 +125,25 @@ vec3 cast_ray(const vec3 &orig, const vec3 &dir, int depth=0) {
} }
int main() { int main() {
const int width = 1024; constexpr int width = 1024;
const int height = 768; constexpr int height = 768;
const float fov = 1.05; // 60 degrees field of view in radians constexpr float fov = 1.05; // 60 degrees field of view in radians
std::vector<vec3> framebuffer(width*height); std::vector<vec3> framebuffer(width*height);
#pragma omp parallel for #pragma omp parallel for
for (int j = 0; j<height; j++) { // actual rendering loop for (int pix = 0; pix<width*height; pix++) { // actual rendering loop
for (int i = 0; i<width; i++) { float dir_x = (pix%width + 0.5) - width/2.;
float dir_x = (i + 0.5) - width/2.; float dir_y = -(pix/width + 0.5) + height/2.; // this flips the image at the same time
float dir_y = -(j + 0.5) + height/2.; // this flips the image at the same time float dir_z = -height/(2.*tan(fov/2.));
float dir_z = -height/(2.*tan(fov/2.)); framebuffer[pix] = cast_ray(vec3{0,0,0}, vec3{dir_x, dir_y, dir_z}.normalized());
framebuffer[i+j*width] = cast_ray(vec3{0,0,0}, vec3{dir_x, dir_y, dir_z}.normalized());
}
} }
std::ofstream ofs; // save the framebuffer to file std::ofstream ofs("./out.ppm", std::ios::binary);
ofs.open("./out.ppm", std::ios::binary);
ofs << "P6\n" << width << " " << height << "\n255\n"; ofs << "P6\n" << width << " " << height << "\n255\n";
for (vec3 &color : framebuffer) { for (vec3 &color : framebuffer) {
float max = std::max(1.f, std::max(color[0], std::max(color[1], color[2]))); float max = std::max(1.f, std::max(color[0], std::max(color[1], color[2])));
for (int chan : {0,1,2}) for (int chan : {0,1,2})
ofs << (char)(255 * color[chan]/max); ofs << (char)(255 * color[chan]/max);
} }
ofs.close();
return 0; return 0;
} }