From 7d46a96a058ced643c8d6f5926b1ee867481e18c Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Tue, 27 Dec 2011 12:21:04 +0100 Subject: [PATCH] Layers, colors, ugly blur (as test) --- Canvas.hpp | 49 ++++++++++++++++++++++++++++-- Tonemapper.hpp | 81 +++++++++++++++++++++++++++++++++++++++++++++----- main.cpp | 10 +++++-- 3 files changed, 127 insertions(+), 13 deletions(-) diff --git a/Canvas.hpp b/Canvas.hpp index 11c2211..f29264d 100644 --- a/Canvas.hpp +++ b/Canvas.hpp @@ -20,14 +20,17 @@ #include #include -#include "array.hpp" +#include +template class Canvas2D { - typedef unsigned int value_type; + typedef T value_type; typedef std::vector Row; typedef std::vector Storage; public: + static constexpr size_t dimension = 2; + Canvas2D(size_t width, size_t height) : storage(height, Row(width, 0)) {} @@ -122,10 +125,18 @@ public: return (*canvas)[r][c]; } + value_type const & operator*() const { + return (*canvas)[r][c]; + } + value_type & operator->(){ return (*canvas)[r][c]; } + value_type const & operator->() const { + return (*canvas)[r][c]; + } + private: friend class Canvas2D; iterator(Canvas2D * canvas, size_t c = 0, size_t r = 0) @@ -198,4 +209,38 @@ private: Storage storage; }; +template +class LayeredCanvas { +public: + static constexpr size_t dimension = Canvas::dimension; + + LayeredCanvas(size_t width, size_t height, size_t layers) + : canvae(layers, Canvas(width, height)) + {} + + Canvas & operator[](size_t layer){ + return canvae[layer]; + } + + Canvas const & operator[](size_t layer) const { + return canvae[layer]; + } + + size_t layers() const { + return canvae.size(); + } + + template + size_t size() const { + return canvae.front().size(); + } + + void plot(double const * position, size_t layer){ + canvae[layer].plot(position); + } + +private: + std::vector canvae; +}; + #endif diff --git a/Tonemapper.hpp b/Tonemapper.hpp index 5dcde94..9913d6c 100644 --- a/Tonemapper.hpp +++ b/Tonemapper.hpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace Tonemappers { @@ -26,21 +27,27 @@ namespace Tonemappers { } template - void process(C const & canvas, I & image){ + void process(C const & canvas, I & image) const { for (typename C::const_iterator it = canvas.begin(); it != canvas.end(); ++it) { const double grayscale = get_value(*it); image << typename I::pixel(grayscale, grayscale, grayscale); } } - - protected: - double get_value(unsigned int n){ + + template + double get_value(T const & n) const { return (double) n / (double) max; } + + protected: unsigned int max; }; struct GammaCorrector : public Normalizer { + GammaCorrector(double gamma = 1.0) + : gamma(gamma) + {} + template void analyse(C const & canvas){ Normalizer::analyse(canvas); @@ -50,18 +57,76 @@ namespace Tonemappers { } template - void process(C const & canvas, I & image){ + void process(C const & canvas, I & image) const { for (typename C::const_iterator it = canvas.begin(); it != canvas.end(); ++it) { const double grayscale = get_value(*it); image << typename I::pixel(grayscale, grayscale, grayscale); } } - protected: - double get_value(unsigned int n){ - return std::pow(Normalizer::get_value(n), power); + template + double get_value(T const & n, double factor = 1.0) const { + return std::pow(Normalizer::get_value(n), factor * power / gamma); } + + protected: double power; + double gamma; + }; + + struct Colorizer { + Colorizer(size_t n_planes) + : gamma_correctors(n_planes) + , gammas() + { + gammas[0].push_back(1.0); + gammas[1].push_back(3.0); + gammas[2].push_back(3.0); + + gammas[0].push_back(3.0); + gammas[1].push_back(1.0); + gammas[2].push_back(1.0); + + colors[0].push_back(3.0); + colors[1].push_back(0.0); + colors[2].push_back(0.0); + + colors[0].push_back(0.0); + colors[1].push_back(2.0); + colors[2].push_back(3.0); + } + + template + void analyse(C const & canvas){ + for (size_t i = 0; i < gamma_correctors.size(); ++i) { + gamma_correctors[i].analyse(canvas[i]); + } + } + + template + typename std::enable_if::type process(C & canvas, I & image) const { + for (unsigned int r = 0; r < canvas.template size<1>(); ++r){ + for (unsigned int c = 0; c < canvas.template size<0>(); ++c){ + auto const c1 = canvas[0][r][c]; + auto const c2 = canvas[1][r][c]; + std::array const a = {{c1, c2}}; + image << typename I::pixel(get_value(a, 0), get_value(a, 1), get_value(a, 2)); + } + } + } + + protected: + template + double get_value(T const & n, size_t color) const { + double ret = 0.0; + for (size_t i = 0; i < n.size(); ++i){ + ret += gamma_correctors[color].get_value(n[i], gammas[color][i]) * colors[color][i]; + } + return ret; + } + std::vector gamma_correctors; + std::array, 3> gammas; + std::array, 3> colors; }; } diff --git a/main.cpp b/main.cpp index ede6770..9351a51 100644 --- a/main.cpp +++ b/main.cpp @@ -35,7 +35,11 @@ void render(Attractor & myAttractor, C & canvas, unsigned int iterations){ for(unsigned int i = 0; i < 1000000; ++i) { myAttractor.iterate(); myAttractor.project(); - canvas.plot(myAttractor.projector->projectedPoint); + canvas.plot(myAttractor.projector->projectedPoint, 0); + double x = rand() / (double) RAND_MAX - 0.5; + double y = rand() / (double) RAND_MAX - 0.5; + double blur[2] = {myAttractor.projector->projectedPoint[0] + x*0.02, myAttractor.projector->projectedPoint[1] + y*0.02}; + canvas.plot(blur, 1); } progress.show(j, iterations); } @@ -67,8 +71,8 @@ int main(int argc, char* argv[]) try { std::string filename = output_path + generate_filename(); - Canvas2D canvas(width, height); Logger logger(std::cout, LOG_VERBOSE); + LayeredCanvas > canvas(width, height, 2); { Attractor my_attractor(attractorFile); @@ -84,7 +88,7 @@ int main(int argc, char* argv[]) try { } { - Tonemappers::GammaCorrector tonemapper; + Tonemappers::Colorizer tonemapper(canvas.layers()); tonemapper.analyse(canvas); logger.start("saving image");