diff options
author | Keuin <[email protected]> | 2022-04-14 13:43:28 +0800 |
---|---|---|
committer | Keuin <[email protected]> | 2022-04-14 14:01:15 +0800 |
commit | 01f5ff46d222ee137a87a69cae430421e50c21b5 (patch) | |
tree | 4cfb490cfb0287c31234f7c2afef463e6926df02 | |
parent | a41fbf75aff54f4d3bd88793cdf2bf281ea9ee01 (diff) |
Use flexible intermediate color depth when rendering.
Note: further debugging is needed. The output image quality won't be improved when using 16bit/32bit internal color depth.
-rw-r--r-- | bitmap.h | 17 | ||||
-rw-r--r-- | main_simple_scanner.cpp | 17 |
2 files changed, 25 insertions, 9 deletions
@@ -136,11 +136,25 @@ public: width(width), height(height), content{data} {} static bitmap<T> average(const std::vector<bitmap<T>> &images) { + using Acc = typename std::conditional< + (sizeof(T) <= 1), + uint_fast16_t, + typename std::conditional< + (sizeof(T) <= 2), + uint_fast32_t, + typename std::conditional< + (sizeof(T) <= 4), + uint_fast64_t, + uintmax_t + >::type + >::type + >::type; // pick the smallest suitable type for accumulator + static_assert(sizeof(Acc) > sizeof(T), "accumulator may overflow"); assert(!images.empty()); bitmap<T> result{images[0].width, images[0].height}; const auto m = images.size(); const auto n = images[0].content.size(); - uint_fast32_t acc_r, acc_g, acc_b; + Acc acc_r, acc_g, acc_b; for (size_t i = 0; i < n; ++i) { acc_r = 0; acc_g = 0; @@ -197,7 +211,6 @@ public: bitmap<T> out{shape.first, shape.second}; for (size_t i = 0; i < sz; ++i) { out[i] = pixel<T>::from(src[i]); - std::cerr << (int) out[i].r << ' ' << (int) out[i].g << ' ' << (int) out[i].b << std::endl; } return out; } diff --git a/main_simple_scanner.cpp b/main_simple_scanner.cpp index bd870d7..26518b1 100644 --- a/main_simple_scanner.cpp +++ b/main_simple_scanner.cpp @@ -17,6 +17,8 @@ #define DEMO_BALL +// T: intermediate color depth +template<typename T> void generate_image(uint16_t image_width, uint16_t image_height, double viewport_width, double focal_length, double sphere_z, double sphere_r, unsigned samples, const std::string &caption = "", unsigned caption_scale = 1) { @@ -26,13 +28,13 @@ void generate_image(uint16_t image_width, uint16_t image_height, double viewport std::cerr << "Antialiasing Samples: " << samples << std::endl; } double r = 1.0 * image_width / image_height; - viewport8b *vp; + viewport<T> *vp; if (samples == 1) { - vp = new basic_viewport8b{viewport_width, viewport_width / r, vec3d{0, 0, -focal_length}}; + vp = new basic_viewport<T>{viewport_width, viewport_width / r, vec3d{0, 0, -focal_length}}; } else { - vp = new aa_viewport8b{viewport_width, viewport_width / r, vec3d{0, 0, -focal_length}, samples}; + vp = new aa_viewport<T>{viewport_width, viewport_width / r, vec3d{0, 0, -focal_length}, samples}; } - hitlist8b world; + hitlist<T> world; world.add_object(std::make_shared<sphere>( vec3d{0, -100.5, -1}, 100)); // the earth @@ -44,11 +46,12 @@ void generate_image(uint16_t image_width, uint16_t image_height, double viewport tm.stop_measure(); if (!caption.empty()) { image.print(caption, - pixel8b::from_normalized(1.0, 0.0, 0.0), + pixel<T>::from_normalized(1.0, 0.0, 0.0), 10, 10, caption_scale, 0.8); } + const auto image8b = bitmap8b::from<T>(image); if (!std::getenv("NOPRINT")) { - image.write_plain_ppm(std::cout); + image8b.write_plain_ppm(std::cout); } else { std::cerr << "NOPRINT is defined. PPM Image won't be printed." << std::endl; } @@ -71,7 +74,7 @@ int main(int argc, char **argv) { cap = std::string{argv[8]}; } const auto image_width = std::stoul(iw); - generate_image(image_width, std::stoul(ih), + generate_image<uint16_t>(image_width, std::stoul(ih), std::stod(vw), std::stod(fl), std::stod(sz), std::stod(sr), std::stoul(sp), cap, |