Start actually piecing together the GLSL shaders from the effect chain.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 1 Oct 2012 15:57:26 +0000 (17:57 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 1 Oct 2012 15:57:33 +0000 (17:57 +0200)
17 files changed:
colorspace_conversion_effect.cpp
colorspace_conversion_effect.h
effect.h
effect_chain.cpp
effect_chain.h
footer.glsl [new file with mode: 0644]
fs.glsl
gamma_expansion_effect.cpp
gamma_expansion_effect.h
header.glsl [new file with mode: 0644]
lift_gamma_gain_effect.cpp
lift_gamma_gain_effect.h
main.cpp
todo.glsl [new file with mode: 0644]
util.cpp
util.h
vs.glsl

index fe8119a..8a0199e 100644 (file)
@@ -1,4 +1,5 @@
 #include "colorspace_conversion_effect.h"
+#include "util.h"
 
 ColorSpaceConversionEffect::ColorSpaceConversionEffect()
        : source_space(COLORSPACE_sRGB),
@@ -7,3 +8,8 @@ ColorSpaceConversionEffect::ColorSpaceConversionEffect()
        register_int("source_space", (int *)&source_space);
        register_int("destination_space", (int *)&destination_space);
 }
+
+std::string ColorSpaceConversionEffect::output_glsl()
+{
+       return read_file("todo.glsl");
+}
index bf3583b..e487d70 100644 (file)
@@ -7,6 +7,7 @@
 class ColorSpaceConversionEffect : public Effect {
 public:
        ColorSpaceConversionEffect();
+       std::string output_glsl();
 
 private:
        ColorSpace source_space, destination_space;
index a7b0e4b..623915b 100644 (file)
--- a/effect.h
+++ b/effect.h
@@ -18,6 +18,7 @@ public:
        virtual bool needs_srgb_primaries() { return true; }
        virtual bool needs_many_samples() { return false; }
        virtual bool needs_mipmaps() { return false; }
+       virtual std::string output_glsl() = 0;
 
        // Neither of these take ownership.
        bool set_int(const std::string&, int value);
index 05adfd8..32ee2ce 100644 (file)
@@ -1,12 +1,19 @@
+#define GL_GLEXT_PROTOTYPES 1
+
+#include <stdio.h>
 #include <assert.h>
 
+#include <GL/gl.h>
+#include <GL/glext.h>
+
+#include "util.h"
 #include "effect_chain.h"
 #include "gamma_expansion_effect.h"
 #include "lift_gamma_gain_effect.h"
 #include "colorspace_conversion_effect.h"
 
 EffectChain::EffectChain(unsigned width, unsigned height)
-       : width(width), height(height) {}
+       : width(width), height(height), finalized(false) {}
 
 void EffectChain::add_input(const ImageFormat &format)
 {
@@ -53,7 +60,40 @@ Effect *EffectChain::add_effect(EffectId effect_id)
                current_color_space = COLORSPACE_sRGB;
        }
 
+       // not handled yet
+       assert(!effect->needs_many_samples());
+       assert(!effect->needs_mipmaps());
+
        effects.push_back(effect);
        return effect;
 }
 
+void EffectChain::finalize()
+{
+       std::string frag_shader = read_file("header.glsl");
+
+       for (unsigned i = 0; i < effects.size(); ++i) {
+               char effect_id[256];
+               sprintf(effect_id, "eff%d", i);
+       
+               frag_shader += "\n";
+               frag_shader += std::string("#define PREFIX(x) ") + effect_id + "_ ## x\n";
+               frag_shader += std::string("#define FUNCNAME ") + effect_id + "\n";
+               frag_shader += effects[i]->output_glsl();
+               frag_shader += "#undef PREFIX\n";
+               frag_shader += "#undef FUNCNAME\n";
+               frag_shader += std::string("#define LAST_INPUT ") + effect_id + "\n";
+               frag_shader += "\n";
+       }
+       printf("%s\n", frag_shader.c_str());
+       
+       glsl_program_num = glCreateProgram();
+       GLhandleARB vs_obj = compile_shader(read_file("vs.glsl"), GL_VERTEX_SHADER);
+       GLhandleARB fs_obj = compile_shader(frag_shader, GL_FRAGMENT_SHADER);
+       glAttachObjectARB(glsl_program_num, vs_obj);
+       check_error();
+       glAttachObjectARB(glsl_program_num, fs_obj);
+       check_error();
+       glLinkProgram(glsl_program_num);
+       check_error();
+}
index c8fe11e..9622abc 100644 (file)
@@ -31,20 +31,29 @@ struct ImageFormat {
 class EffectChain {
 public:
        EffectChain(unsigned width, unsigned height);
+
+       // input, effects, output, finalize need to come in that specific order.
+
        void add_input(const ImageFormat &format);
 
-       // The pointer is owned by EffectChain.
+       // The returned pointer is owned by EffectChain.
        Effect *add_effect(EffectId effect);
 
        void add_output(const ImageFormat &format);
+       void finalize();
 
-       void render(unsigned char *src, unsigned char *dst);
+       //void render(unsigned char *src, unsigned char *dst);
+       void render_to_screen(unsigned char *src);
 
 private:
        unsigned width, height;
        ImageFormat input_format, output_format;
        std::vector<Effect *> effects;
 
+       int glsl_program_num;
+       bool finalized;
+
+       // Used during the building of the effect chain.
        ColorSpace current_color_space;
        GammaCurve current_gamma_curve; 
 };
diff --git a/footer.glsl b/footer.glsl
new file mode 100644 (file)
index 0000000..0a742a3
--- /dev/null
@@ -0,0 +1,4 @@
+void main()
+{
+       gl_FragColor = LAST_INPUT(tc);
+}
diff --git a/fs.glsl b/fs.glsl
index 2637869..25f20db 100644 (file)
--- a/fs.glsl
+++ b/fs.glsl
@@ -1,6 +1,6 @@
 #version 120
 uniform sampler2D tex;
-varying vec4 tc;
+varying vec2 tc;
 uniform vec3 lift, gain;
 uniform vec3 gain_pow_inv_gamma, inv_gamma_22;
 uniform float saturation;
@@ -40,7 +40,7 @@ vec3 from_linear(vec3 x) {
 
 void main()
 {
-       vec3 x = texture2D(tex, tc.st, -30.0f).rgb;
+       vec3 x = texture2D(tex, tc).rgb;
        x = to_linear(x);
 
        // do lift in nonlinear space (the others don't care)
index cef1416..1748ae9 100644 (file)
@@ -1,7 +1,13 @@
 #include "gamma_expansion_effect.h"
+#include "util.h"
 
 GammaExpansionEffect::GammaExpansionEffect()
        : source_curve(GAMMA_LINEAR)
 {
        register_int("source_curve", (int *)&source_curve);
 }
+
+std::string GammaExpansionEffect::output_glsl()
+{
+       return read_file("todo.glsl");
+}
index 497a38c..d161c92 100644 (file)
@@ -7,6 +7,7 @@
 class GammaExpansionEffect : public Effect {
 public:
        GammaExpansionEffect();
+       std::string output_glsl();
 
 private:
        GammaCurve source_curve;
diff --git a/header.glsl b/header.glsl
new file mode 100644 (file)
index 0000000..274cb90
--- /dev/null
@@ -0,0 +1,9 @@
+uniform sampler2D input_tex;
+varying vec2 tc;
+
+vec4 read_input(vec2 tc)
+{
+       vec3 x = texture2D(input_tex, tc.st);
+}
+
+#define LAST_INPUT read_input
index 5c83854..eef04d5 100644 (file)
@@ -1,4 +1,5 @@
 #include "lift_gamma_gain_effect.h"
+#include "util.h"
 
 LiftGammaGainEffect::LiftGammaGainEffect()
        : lift(0.0f, 0.0f, 0.0f),
@@ -11,3 +12,8 @@ LiftGammaGainEffect::LiftGammaGainEffect()
        register_vec3("gain", (float *)&gain);
        register_float("saturation", &saturation);
 }
+
+std::string LiftGammaGainEffect::output_glsl()
+{
+       return read_file("todo.glsl");
+}
index ae71448..26eb583 100644 (file)
@@ -6,6 +6,7 @@
 class LiftGammaGainEffect : public Effect {
 public:
        LiftGammaGainEffect();
+       std::string output_glsl();
 
 private:
        RGBTriplet lift, gamma, gain;
index 8c28c8f..4054636 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -38,31 +38,6 @@ float lift_r = 0.0f, lift_g = 0.0f, lift_b = 0.0f;
 float gamma_r = 1.0f, gamma_g = 1.0f, gamma_b = 1.0f;
 float gain_r = 1.0f, gain_g = 1.0f, gain_b = 1.0f;
 
-GLhandleARB read_shader(const char* filename, GLenum type)
-{
-       std::string shader_src = read_file(filename);
-
-       GLhandleARB obj = glCreateShaderObjectARB(type);
-       const GLchar* source[] = { shader_src.data() };
-       const GLint length[] = { shader_src.size() };
-       glShaderSource(obj, 1, source, length);
-       glCompileShader(obj);
-
-       GLchar info_log[4096];
-       GLsizei log_length = sizeof(info_log) - 1;
-       glGetShaderInfoLog(obj, log_length, &log_length, info_log);
-       info_log[log_length] = 0; 
-       printf("shader compile log: %s\n", info_log);
-
-       GLint status;
-       glGetShaderiv(obj, GL_COMPILE_STATUS, &status);
-       if (status == GL_FALSE) {
-               exit(1);
-       }
-
-       return obj;
-}
-
 void draw_picture_quad(GLint prog, int frame)
 {
        glUseProgramObjectARB(prog);
@@ -251,6 +226,19 @@ int main(int argc, char **argv)
        check_error();
 
        load_texture("blg_wheels_woman_1.jpg");
+
+       EffectChain chain(WIDTH, HEIGHT);
+
+       ImageFormat inout_format;
+       inout_format.pixel_format = FORMAT_RGB;
+       inout_format.color_space = COLORSPACE_sRGB;
+       inout_format.gamma_curve = GAMMA_sRGB;
+
+       chain.add_input(inout_format);
+       Effect *lift_gamma_gain_effect = chain.add_effect(LIFT_GAMMA_GAIN);
+       chain.add_output(inout_format);
+       chain.finalize();
+
        //glGenerateMipmap(GL_TEXTURE_2D);
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 4);
        //check_error();
@@ -306,8 +294,8 @@ int main(int argc, char **argv)
        update_hsv();
 
        int prog = glCreateProgram();
-       GLhandleARB vs_obj = read_shader("vs.glsl", GL_VERTEX_SHADER);
-       GLhandleARB fs_obj = read_shader("fs.glsl", GL_FRAGMENT_SHADER);
+       GLhandleARB vs_obj = compile_shader(read_file("vs.glsl"), GL_VERTEX_SHADER);
+       GLhandleARB fs_obj = compile_shader(read_file("fs.glsl"), GL_FRAGMENT_SHADER);
        glAttachObjectARB(prog, vs_obj);
        check_error();
        glAttachObjectARB(prog, fs_obj);
@@ -344,6 +332,7 @@ int main(int argc, char **argv)
 
                ++frame;
 
+               
                draw_picture_quad(prog, frame);
                
                glReadPixels(0, 0, WIDTH, HEIGHT, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, BUFFER_OFFSET(0));
diff --git a/todo.glsl b/todo.glsl
new file mode 100644 (file)
index 0000000..a428697
--- /dev/null
+++ b/todo.glsl
@@ -0,0 +1,5 @@
+// Placeholder for effects that are not done yet.
+vec4 FUNCNAME(vec2 tc)
+{
+       return LAST_INPUT(tc);
+}
index b427625..c18f009 100644 (file)
--- a/util.cpp
+++ b/util.cpp
@@ -1,5 +1,12 @@
-#include <math.h>
+#define GL_GLEXT_PROTOTYPES 1
+
+#include <stdio.h>
+#include <assert.h>
 
+#include <GL/gl.h>
+#include <GL/glext.h>
+
+#include <math.h>
 #include "util.h"
 
 void hsv2rgb(float h, float s, float v, float *r, float *g, float *b)
@@ -57,3 +64,27 @@ std::string read_file(const std::string &filename)
 
        return std::string(buf, len);
 }
+
+GLhandleARB compile_shader(const std::string &shader_src, GLenum type)
+{
+       GLhandleARB obj = glCreateShaderObjectARB(type);
+       const GLchar* source[] = { shader_src.data() };
+       const GLint length[] = { shader_src.size() };
+       glShaderSource(obj, 1, source, length);
+       glCompileShader(obj);
+
+       GLchar info_log[4096];
+       GLsizei log_length = sizeof(info_log) - 1;
+       glGetShaderInfoLog(obj, log_length, &log_length, info_log);
+       info_log[log_length] = 0; 
+       printf("shader compile log: %s\n", info_log);
+
+       GLint status;
+       glGetShaderiv(obj, GL_COMPILE_STATUS, &status);
+       if (status == GL_FALSE) {
+               exit(1);
+       }
+
+       return obj;
+}
+
diff --git a/util.h b/util.h
index 3957b86..a6ca0e8 100644 (file)
--- a/util.h
+++ b/util.h
@@ -6,10 +6,13 @@
 
 #include <string>
 
+#include <GL/gl.h>
+
 // assumes h in [0, 2pi> or [-pi, pi>
 void hsv2rgb(float h, float s, float v, float *r, float *g, float *b);
 
 std::string read_file(const std::string &filename);
+GLhandleARB compile_shader(const std::string &shader_src, GLenum type);
 
 #ifdef NDEBUG
 #define check_error()
diff --git a/vs.glsl b/vs.glsl
index b6db3cb..4d79aaf 100644 (file)
--- a/vs.glsl
+++ b/vs.glsl
@@ -1,5 +1,5 @@
 #version 120
-varying vec4 tc;
+varying vec2 tc;
 //varying vec3 lift, inv_gamma, gain;
 //uniform vec3 gamma;
 //varying vec3 inv_gamma;
@@ -15,7 +15,7 @@ vec3 to_linear(vec3 x) {
 
 void main()
 {
-        tc = gl_MultiTexCoord0;
+        tc = gl_MultiTexCoord0.st;
 
        //lift = to_linear(vec3(rgba.r, 0.0, 0.0));
        //lift = vec3(rgba.r, 0.0, 0.0);