Layers, colors, ugly blur (as test)
This commit is contained in:
parent
620b4c331c
commit
7d46a96a05
3 changed files with 127 additions and 13 deletions
49
Canvas.hpp
49
Canvas.hpp
|
@ -20,14 +20,17 @@
|
|||
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include "array.hpp"
|
||||
#include <array>
|
||||
|
||||
template <typename T>
|
||||
class Canvas2D {
|
||||
typedef unsigned int value_type;
|
||||
typedef T value_type;
|
||||
typedef std::vector<value_type> Row;
|
||||
typedef std::vector<Row> 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 <typename Canvas>
|
||||
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 N>
|
||||
size_t size() const {
|
||||
return canvae.front().size<N>();
|
||||
}
|
||||
|
||||
void plot(double const * position, size_t layer){
|
||||
canvae[layer].plot(position);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Canvas> canvae;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <cmath>
|
||||
#include <array>
|
||||
|
||||
namespace Tonemappers {
|
||||
|
||||
|
@ -26,21 +27,27 @@ namespace Tonemappers {
|
|||
}
|
||||
|
||||
template <typename C, typename I>
|
||||
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 <typename T>
|
||||
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 <typename C>
|
||||
void analyse(C const & canvas){
|
||||
Normalizer::analyse(canvas);
|
||||
|
@ -50,18 +57,76 @@ namespace Tonemappers {
|
|||
}
|
||||
|
||||
template <typename C, typename I>
|
||||
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 <typename T>
|
||||
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 <typename C>
|
||||
void analyse(C const & canvas){
|
||||
for (size_t i = 0; i < gamma_correctors.size(); ++i) {
|
||||
gamma_correctors[i].analyse(canvas[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename C, typename I>
|
||||
typename std::enable_if<C::dimension == 2, void>::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<decltype(c1), 2> const a = {{c1, c2}};
|
||||
image << typename I::pixel(get_value(a, 0), get_value(a, 1), get_value(a, 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename T>
|
||||
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<GammaCorrector> gamma_correctors;
|
||||
std::array<std::vector<double>, 3> gammas;
|
||||
std::array<std::vector<double>, 3> colors;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
10
main.cpp
10
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<Canvas2D<unsigned int> > 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");
|
||||
|
|
Reference in a new issue