#ifndef CAMERA_H #define CAMERA_H #include "common.h" #include "hittable.h" class Camera { public: double aspect_ratio = 1.0; // Ratio of image width over height int image_width = 100; // Rendered image width in pixel count void render(const hittable &world, Canvas &canvas) { initialize(); for (int j = 0; j < canvas.height; j++) { for (int i = 0; i < canvas.width; i++) { auto pixel_center = pixel00_loc + (i * pixel_delta_u) + (j * pixel_delta_v); auto ray_direction = pixel_center - center; Ray r(center, ray_direction); canvas.set_pixel(i, j, ray_color(r, world)); } } } void move_to(Point3 loc) { center = loc; } Point3 position() { return center; } private: int image_height; // Rendered image height Point3 center = Point3(0, 0, 0); Point3 pixel00_loc; // Location of pixel 0, 0 Vec3 pixel_delta_u; // Offset to pixel to the right Vec3 pixel_delta_v; // Offset to pixel below void initialize() { image_height = int(image_width / aspect_ratio); image_height = (image_height < 1) ? 1 : image_height; // Determine viewport dimensions. auto focal_length = 1.0; auto viewport_height = 2.0; auto viewport_width = viewport_height * (double(image_width) / image_height); // Calculate the vectors across the horizontal and down the vertical // viewport edges. auto viewport_u = Vec3(viewport_width, 0, 0); auto viewport_v = Vec3(0, -viewport_height, 0); // Calculate the horizontal and vertical delta vectors from pixel to pixel. pixel_delta_u = viewport_u / image_width; pixel_delta_v = viewport_v / image_height; // Calculate the location of the upper left pixel. auto viewport_upper_left = center - Vec3(0, 0, focal_length) - viewport_u / 2 - viewport_v / 2; pixel00_loc = viewport_upper_left + 0.5 * (pixel_delta_u + pixel_delta_v); } Color ray_color(const Ray &r, const hittable &world) { hit_record rec; if (world.hit(r, 0, infinity, rec)) { return 0.5 * (rec.normal + Color(1, 1, 1)); } return Color(0, 0, 0); } }; #endif