Browse Source

Layers, colors, ugly blur (as test)

master
Joshua Moerman 13 years ago
parent
commit
7d46a96a05
  1. 49
      Canvas.hpp
  2. 79
      Tonemapper.hpp
  3. 10
      main.cpp

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

79
Tonemapper.hpp

@ -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

@ -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");