X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Feffects%2Fcolorcurve.cpp;fp=source%2Feffects%2Fcolorcurve.cpp;h=8811b065fd3b6f0dddddd86a8e091e08d97bc224;hp=0000000000000000000000000000000000000000;hb=7aaec9a70b8d7733429bec043f8e33e02956f266;hpb=bec07999d95b76f4b47cffcc564d0cd0afc0435e diff --git a/source/effects/colorcurve.cpp b/source/effects/colorcurve.cpp new file mode 100644 index 00000000..8811b065 --- /dev/null +++ b/source/effects/colorcurve.cpp @@ -0,0 +1,124 @@ +#include +#include "color.h" +#include "colorcurve.h" +#include "mesh.h" +#include "renderer.h" +#include "shader.h" +#include "texture2d.h" + +using namespace std; + +namespace Msp { +namespace GL { + +ColorCurve::ColorCurve(): + shprog("colorcurve.glsl"), + quad(get_fullscreen_quad()), + linear_sampler(get_linear_sampler()), + nearest_sampler(get_nearest_sampler()) +{ + shdata.uniform("source", 0); + shdata.uniform("curve", 1); + + curve.storage(LUMINANCE8, 256, 1); + texturing.attach(1, curve, linear_sampler.get()); + + set_exposure_adjust(0.0f); + set_brightness_response(0.4f); + set_linear(); +} + +void ColorCurve::set_exposure_adjust(float e) +{ + shdata.uniform("exposure", pow(2.0f, e)); +} + +void ColorCurve::set_brightness_response(float b) +{ + if(b<=0 || b>1) + throw invalid_argument("ColorCurve::set_brightness_response"); + float t = (b<1 ? pow(b, 1/(1-b)) : 0.0f); + shdata.uniform("brightness_response", b, t, pow(t, b)); +} + +void ColorCurve::set_gamma(float g) +{ + if(g<0.1 || g>10) + throw invalid_argument("ColorCurve::set_gamma"); + + unsigned char curve_data[256]; + for(unsigned i=0; i<256; ++i) + curve_data[i] = pow(i/255.0f, 1/g)*255+0.5f; + curve.image(0, curve_data); +} + +void ColorCurve::set_srgb() +{ + unsigned char curve_data[256]; + curve_data[0] = 0; + for(unsigned i=1; i<256; ++i) + curve_data[i] = to_srgb(i/255.0f)*255+0.5f; + curve.image(0, curve_data); +} + +void ColorCurve::set_linear() +{ + unsigned char curve_data[256]; + for(unsigned i=0; i<256; ++i) + curve_data[i] = i; + curve.image(0, curve_data); +} + +void ColorCurve::render(Renderer &renderer, const Texture2D &color_buf, const Texture2D &) +{ + texturing.attach(0, color_buf, nearest_sampler.get()); + + Renderer::Push push(renderer); + renderer.set_shader_program(&shprog, &shdata); + renderer.set_texturing(&texturing); + quad->draw(renderer); +} + + +ColorCurve::Template::Template(): + exposure_adjust(0.0f), + brightness_response(0.4f), + gamma(1.0f), + srgb(false) +{ } + +ColorCurve *ColorCurve::Template::create(unsigned, unsigned) const +{ + RefPtr colorcurve = new ColorCurve; + colorcurve->set_exposure_adjust(exposure_adjust); + colorcurve->set_brightness_response(brightness_response); + if(srgb) + colorcurve->set_srgb(); + else + colorcurve->set_gamma(gamma); + return colorcurve.release(); +} + + +ColorCurve::Template::Loader::Loader(Template &t): + DataFile::DerivedObjectLoader(t) +{ + add("brightness_response", &Template::brightness_response); + add("exposure_adjust", &Template::exposure_adjust); + add("gamma", &Loader::gamma); + add("srgb", &Loader::srgb); +} + +void ColorCurve::Template::Loader::gamma(float g) +{ + obj.gamma = g; + obj.srgb = false; +} + +void ColorCurve::Template::Loader::srgb() +{ + obj.srgb = true; +} + +} // namespace GL +} // namespace Msp