From 86f457710df5346e63d52da468db104cd5354f61 Mon Sep 17 00:00:00 2001 From: Keuin Date: Mon, 11 Apr 2022 22:49:48 +0800 Subject: Decouple viewport size and generated image size. Use cli parameters to control simple_scanner. --- main_simple_scanner.cpp | 54 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/main_simple_scanner.cpp b/main_simple_scanner.cpp index a1d75f7..103cfab 100644 --- a/main_simple_scanner.cpp +++ b/main_simple_scanner.cpp @@ -12,10 +12,10 @@ class viewport { - uint16_t width, height; - vec3d center; - bitmap8b bitmap_{width, height}; + double half_width, half_height; // viewport size + vec3d center; // coordinate of the viewport center point + // Given a ray from the camera, generate a color the camera seen on the viewport. static pixel8b color(const ray3d &r) { const auto u = (r.direction().y + 1.0) * 0.5; return mix( @@ -29,32 +29,48 @@ class viewport { public: viewport() = delete; - viewport(uint16_t width, uint16_t height, vec3d viewport_center) : - width(width), height(height), center(viewport_center) {} + viewport(double width, double height, vec3d viewport_center) : + half_width(width / 2.0), half_height(height / 2.0), center(viewport_center) {} - void render(vec3d viewpoint) { + // Generate the image seen on given viewpoint. + bitmap8b render(vec3d viewpoint, uint16_t image_width, uint16_t image_height) { + bitmap8b image{image_width, image_height}; const auto r = center - viewpoint; - const int half_width = width / 2, half_height = height / 2; - for (int j = -half_height; j < half_height; ++j) { - for (int i = -half_width; i < half_width; ++i) { - const auto dir = r + vec3d{static_cast(i), static_cast(j), 0}; + const int img_hw = image_width / 2, img_hh = image_height / 2; + // iterate over every pixel on the image + for (int j = -img_hh; j < img_hh; ++j) { // axis y + for (int i = -img_hw; i < img_hw; ++i) { // axis x + const vec3d off{ + .x=1.0 * i / half_width, + .y=1.0 * j / half_height, + .z=0.0 + }; // offset on screen plane + const auto dir = r + off; // direction vector from camera to current pixel on screen const ray3d ray{viewpoint, dir}; // from camera to pixel (on the viewport) const auto pixel = color(ray); - bitmap_.set(i + half_width, j + half_height, pixel); + image.set(i + img_hw, j + img_hh, pixel); } } - } - - const bitmap8b &bitmap() const { - return bitmap_; + return image; } }; -int main() { - viewport vp{1920, 1080, vec3d{0, 0, -100}}; +void generate_image(uint16_t image_width, uint16_t image_height, double viewport_width, double focal_length) { + double r = 1.0 * image_width / image_height; + viewport vp{viewport_width, viewport_width / r, vec3d{0, 0, -focal_length}}; timer tm; tm.start_measure(); - vp.render(vec3d{0, 0, 0}); // camera position as the coordinate origin + const auto image = vp.render(vec3d::zero(), image_width, image_height); // camera position as the coordinate origin tm.stop_measure(); - vp.bitmap().write_plain_ppm(std::cout); + image.write_plain_ppm(std::cout); +} + +int main(int argc, char **argv) { + if (argc != 5) { + printf("Usage: %s \n", argv[0]); + return 0; + } + std::string iw{argv[1]}, ih{argv[2]}, vw{argv[3]}, fl{argv[4]}; + generate_image(std::stoul(iw), std::stoul(ih), + std::stod(vw), std::stod(fl)); } \ No newline at end of file -- cgit v1.2.3