74 lines
2.1 KiB
C++
74 lines
2.1 KiB
C++
#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
|