fstream is a proper RAII object

This commit is contained in:
Dmitry V. Sokolov 2022-03-18 17:33:28 +01:00
parent d379242317
commit ce6b7852b7

View File

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