From aa987216b92584aafc0ecbc3d578606018078f91 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 28 Dec 2013 17:14:07 +0200 Subject: [PATCH] Add gamma correction and sRGB conversion support to ColorCurve --- source/colorcurve.cpp | 47 ++++++++++++++++++++++++++++++++++++++----- source/colorcurve.h | 6 ++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/source/colorcurve.cpp b/source/colorcurve.cpp index ae09b7e6..6351ea20 100644 --- a/source/colorcurve.cpp +++ b/source/colorcurve.cpp @@ -1,3 +1,4 @@ +#include #include "colorcurve.h" #include "mesh.h" #include "shader.h" @@ -9,6 +10,7 @@ namespace { static const char fragment_src[] = "uniform sampler2D texture;\n" + "uniform sampler1D curve;\n" "uniform float peak;\n" "uniform float brightness;\n" "varying vec2 texcoord;\n" @@ -21,17 +23,15 @@ static const char fragment_src[] = " vec3 saturated = sample.rgb/maxc;\n" " if(maxc>1.0+peak)\n" " {\n" - " gl_FragColor.rgb = mix(vec3(1.0), saturated, 1.0/pow(brightness, maxc-1.0-peak));\n" + " sample.rgb = mix(vec3(1.0), saturated, 1.0/pow(brightness, maxc-1.0-peak));\n" " }\n" " else\n" " {\n" " float x = (1.0+peak-maxc)/(2.0*peak);\n" - " gl_FragColor.rgb = saturated.rgb*(1.0-peak+(1.0-x*x)*peak);\n" + " sample.rgb = saturated.rgb*(1.0-peak+(1.0-x*x)*peak);\n" " }\n" - " gl_FragColor.a = sample.a;\n" " }\n" - " else\n" - " gl_FragColor = sample;\n" + " gl_FragColor = vec4(texture1D(curve, sample.r).r, texture1D(curve, sample.g).r, texture1D(curve, sample.b).r, sample.a);\n" "}"; } @@ -46,8 +46,16 @@ ColorCurve::ColorCurve(): shprog.attach_shader_owned(new FragmentShader(fragment_src)); shprog.link(); + shdata.uniform("texture", 0); + shdata.uniform("curve", 1); + + curve.storage(LUMINANCE, 256); + curve.set_min_filter(LINEAR); + curve.set_wrap(CLAMP_TO_EDGE); + set_peak(0.2); set_brightness(1.5); + set_linear(); } void ColorCurve::set_peak(float p) @@ -64,11 +72,40 @@ void ColorCurve::set_brightness(float b) shdata.uniform("brightness", 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, LUMINANCE, UNSIGNED_BYTE, 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] = (1.055*pow(i/255.0f, 1/2.4f)-0.055)*255+0.5; + curve.image(0, LUMINANCE, UNSIGNED_BYTE, 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, LUMINANCE, UNSIGNED_BYTE, curve_data); +} + void ColorCurve::render(const Texture2D &color_buf, const Texture2D &) { Bind _bind_shader(shprog); shdata.apply(); Bind _bind_tex(color_buf); + Bind _bind_curve(curve, 1); quad.draw(); } diff --git a/source/colorcurve.h b/source/colorcurve.h index 74a19d04..75e7fd30 100644 --- a/source/colorcurve.h +++ b/source/colorcurve.h @@ -4,6 +4,7 @@ #include "postprocessor.h" #include "program.h" #include "programdata.h" +#include "texture1d.h" namespace Msp { namespace GL { @@ -20,6 +21,7 @@ class ColorCurve: public PostProcessor private: Program shprog; ProgramData shdata; + Texture1D curve; const Mesh &quad; public: @@ -33,6 +35,10 @@ public: saturated value. */ void set_brightness(float); + void set_gamma(float); + void set_srgb(); + void set_linear(); + virtual void render(const Texture2D &, const Texture2D &); }; -- 2.45.2