Make Input an abstract base class, and move the current functionality into FlatInput...
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 6 Oct 2012 13:35:53 +0000 (15:35 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 6 Oct 2012 13:35:53 +0000 (15:35 +0200)
Makefile
effect_chain.cpp
effect_chain.h
flat_input.cpp [moved from input.cpp with 91% similarity]
flat_input.frag [moved from input.frag with 100% similarity]
flat_input.h [new file with mode: 0644]
input.h
main.cpp

index 8b8b655..51aebc5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ CXXFLAGS=-Wall -g
 LDFLAGS=-lSDL -lSDL_image -lGL
 
 # Core.
-OBJS=main.o util.o widgets.o effect.o effect_chain.o input.o
+OBJS=main.o util.o widgets.o effect.o effect_chain.o flat_input.o
 
 # Effects.
 OBJS += lift_gamma_gain_effect.o
index 7232dcb..82e9c5d 100644 (file)
@@ -24,16 +24,15 @@ EffectChain::EffectChain(unsigned width, unsigned height)
          height(height),
          finalized(false) {}
 
-Input *EffectChain::add_input(const ImageFormat &format)
+Input *EffectChain::add_input(Input *input)
 {
        char eff_id[256];
        sprintf(eff_id, "src_image%u", (unsigned)inputs.size());
 
-       Input *input = new Input(format, width, height);
        effects.push_back(input);
        inputs.push_back(input);
-       output_color_space.insert(std::make_pair(input, format.color_space));
-       output_gamma_curve.insert(std::make_pair(input, format.gamma_curve));
+       output_color_space.insert(std::make_pair(input, input->get_color_space()));
+       output_gamma_curve.insert(std::make_pair(input, input->get_gamma_curve()));
        effect_ids.insert(std::make_pair(input, eff_id));
        incoming_links.insert(std::make_pair(input, std::vector<Effect *>()));
        return input;
index f9e1255..0b07b85 100644 (file)
@@ -15,7 +15,9 @@ public:
        // User API:
        // input, effects, output, finalize need to come in that specific order.
 
-       Input *add_input(const ImageFormat &format);
+       // EffectChain takes ownership of the given input.
+       // input is returned back for convenience.
+       Input *add_input(Input *input);
 
        // EffectChain takes ownership of the given effect.
        // effect is returned back for convenience.
similarity index 91%
rename from input.cpp
rename to flat_input.cpp
index 1df39c6..2541dc4 100644 (file)
--- a/input.cpp
@@ -5,10 +5,10 @@
 #include <GL/glext.h>
 #include <assert.h>
 
-#include "input.h"
+#include "flat_input.h"
 #include "util.h"
 
-Input::Input(ImageFormat image_format, unsigned width, unsigned height)
+FlatInput::FlatInput(ImageFormat image_format, unsigned width, unsigned height)
        : image_format(image_format),
          needs_update(false),
          finalized(false),
@@ -22,7 +22,7 @@ Input::Input(ImageFormat image_format, unsigned width, unsigned height)
        register_int("needs_mipmaps", &needs_mipmaps);
 }
 
-void Input::finalize()
+void FlatInput::finalize()
 {
        // Translate the input format to OpenGL's enums.
        GLenum internal_format;
@@ -81,7 +81,7 @@ void Input::finalize()
        finalized = true;
 }
        
-void Input::set_gl_state(GLuint glsl_program_num, const std::string& prefix, unsigned *sampler_num)
+void FlatInput::set_gl_state(GLuint glsl_program_num, const std::string& prefix, unsigned *sampler_num)
 {
        glActiveTexture(GL_TEXTURE0 + *sampler_num);
        check_error();
@@ -119,7 +119,7 @@ void Input::set_gl_state(GLuint glsl_program_num, const std::string& prefix, uns
        ++*sampler_num;
 }
 
-std::string Input::output_fragment_shader()
+std::string FlatInput::output_fragment_shader()
 {
-       return read_file("input.frag");
+       return read_file("flat_input.frag");
 }
similarity index 100%
rename from input.frag
rename to flat_input.frag
diff --git a/flat_input.h b/flat_input.h
new file mode 100644 (file)
index 0000000..a906a5d
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef _FLAT_INPUT_H
+#define _FLAT_INPUT_H 1
+
+#include "input.h"
+
+// A FlatInput is the normal, “classic” case of an input, where everything
+// comes from a single 2D array with chunky pixels.
+class FlatInput : public Input {
+public:
+       FlatInput(ImageFormat format, unsigned width, unsigned height);
+
+       // Create the texture itself. We cannot do this in the constructor,
+       // because we don't necessarily know all the settings (sRGB texture,
+       // mipmap generation) at that point.
+       void finalize();
+
+       std::string output_fragment_shader();
+
+       // Uploads the texture if it has changed since last time.
+       void set_gl_state(GLuint glsl_program_num, const std::string& prefix, unsigned *sampler_num);
+
+       ColorSpace get_color_space() { return image_format.color_space; }
+       GammaCurve get_gamma_curve() { return image_format.gamma_curve; }
+
+       // Tells the input where to fetch the actual pixel data. Note that if you change
+       // this data, you must either call set_pixel_data() again (using the same pointer
+       // is fine), or invalidate_pixel_data(). Otherwise, the texture won't be re-uploaded
+       // on subsequent frames.
+       void set_pixel_data(const unsigned char *pixel_data)
+       {
+               this->pixel_data = pixel_data;
+               invalidate_pixel_data();
+       }
+
+       void invalidate_pixel_data()
+       {
+               needs_update = true;
+       }
+
+       const unsigned char *get_pixel_data() const
+       {
+               return pixel_data;
+       }
+
+       void set_pitch(unsigned pitch) {
+               assert(!finalized);
+               this->pitch = pitch;
+       }
+
+       unsigned get_pitch() {
+               return pitch;
+       }
+
+private:
+       ImageFormat image_format;
+       GLenum format;
+       GLuint pbo, texture_num;
+       bool needs_update, finalized;
+       int use_srgb_texture_format, needs_mipmaps;
+       unsigned width, height, pitch, bytes_per_pixel;
+       const unsigned char *pixel_data;
+};
+
+#endif // !defined(_FLAT_INPUT_H)
diff --git a/input.h b/input.h
index d41b266..ac03e84 100644 (file)
--- a/input.h
+++ b/input.h
@@ -7,61 +7,25 @@
 #include "image_format.h"
 
 // An input is a degenerate case of an effect; it represents the picture data
-// that comes from the user. As such, it has zero “inputs” itself, and some of
-// the normal operations don't really make sense for it.
+// that comes from the user. As such, it has zero “inputs” itself. Also, it
+// has an extra operation called finalize(), which runs when the effect chain
+// is finalized.
+//
+// An input is, like any other effect, required to be able to output a GLSL
+// fragment giving a RGBA value (although that GLSL fragment will have zero
+// inputs itself), and set the required OpenGL state on set_gl_state(),
+// including possibly uploading the texture if so required.
 class Input : public Effect {
 public:
-       Input(ImageFormat format, unsigned width, unsigned height);
-
-       unsigned num_inputs() const { return 0; }
+       virtual unsigned num_inputs() const { return 0; }
 
        // Create the texture itself. We cannot do this in the constructor,
        // because we don't necessarily know all the settings (sRGB texture,
        // mipmap generation) at that point.
-       void finalize();
-
-       std::string output_fragment_shader();
-
-       // Uploads the texture if it has changed since last time.
-       void set_gl_state(GLuint glsl_program_num, const std::string& prefix, unsigned *sampler_num);
-
-       // Tells the input where to fetch the actual pixel data. Note that if you change
-       // this data, you must either call set_pixel_data() again (using the same pointer
-       // is fine), or invalidate_pixel_data(). Otherwise, the texture won't be re-uploaded
-       // on subsequent frames.
-       void set_pixel_data(const unsigned char *pixel_data)
-       {
-               this->pixel_data = pixel_data;
-               invalidate_pixel_data();
-       }
-
-       void invalidate_pixel_data()
-       {
-               needs_update = true;
-       }
-
-       const unsigned char *get_pixel_data() const
-       {
-               return pixel_data;
-       }
-
-       void set_pitch(unsigned pitch) {
-               assert(!finalized);
-               this->pitch = pitch;
-       }
-
-       unsigned get_pitch() {
-               return pitch;
-       }
+       virtual void finalize() = 0;
 
-private:
-       ImageFormat image_format;
-       GLenum format;
-       GLuint pbo, texture_num;
-       bool needs_update, finalized;
-       int use_srgb_texture_format, needs_mipmaps;
-       unsigned width, height, pitch, bytes_per_pixel;
-       const unsigned char *pixel_data;
+       virtual ColorSpace get_color_space() = 0;       
+       virtual GammaCurve get_gamma_curve() = 0;       
 };
 
 #endif // !defined(_INPUT_H)
index bc52e1d..4fbcdf3 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -26,6 +26,7 @@
 #include "util.h"
 #include "widgets.h"
 
+#include "flat_input.h"
 #include "lift_gamma_gain_effect.h"
 #include "saturation_effect.h"
 #include "diffusion_effect.h"
@@ -168,7 +169,8 @@ int main(int argc, char **argv)
        inout_format.color_space = COLORSPACE_sRGB;
        inout_format.gamma_curve = GAMMA_sRGB;
 
-       Input *input = chain.add_input(inout_format);
+       FlatInput *input = new FlatInput(inout_format, WIDTH, HEIGHT);
+       chain.add_input(input);
        Effect *lift_gamma_gain_effect = chain.add_effect(new LiftGammaGainEffect());
        Effect *saturation_effect = chain.add_effect(new SaturationEffect());
        Effect *diffusion_effect = chain.add_effect(new DiffusionEffect());