]> git.sesse.net Git - movit/blob - effect_chain.h
f9e1255566fbcf5522de9a58d34b2f52a83154af
[movit] / effect_chain.h
1 #ifndef _EFFECT_CHAIN_H
2 #define _EFFECT_CHAIN_H 1
3
4 #include <set>
5 #include <vector>
6
7 #include "effect.h"
8 #include "image_format.h"
9 #include "input.h"
10
11 class EffectChain {
12 public:
13         EffectChain(unsigned width, unsigned height);
14
15         // User API:
16         // input, effects, output, finalize need to come in that specific order.
17
18         Input *add_input(const ImageFormat &format);
19
20         // EffectChain takes ownership of the given effect.
21         // effect is returned back for convenience.
22         Effect *add_effect(Effect *effect) {
23                 return add_effect(effect, last_added_effect());
24         }
25         Effect *add_effect(Effect *effect, Effect *input) {
26                 std::vector<Effect *> inputs;
27                 inputs.push_back(input);
28                 return add_effect(effect, inputs);
29         }
30         Effect *add_effect(Effect *effect, Effect *input1, Effect *input2) {
31                 std::vector<Effect *> inputs;
32                 inputs.push_back(input1);
33                 inputs.push_back(input2);
34                 return add_effect(effect, inputs);
35         }
36         Effect *add_effect(Effect *effect, const std::vector<Effect *> &inputs);
37
38         // Similar to add_effect, but:
39         //
40         //  * Does not insert any normalizing effects.
41         //  * Does not ask the effect to insert itself, so it won't work
42         //    with meta-effects.
43         //
44         // We should really separate out these two “sides” of Effect in the
45         // type system soon.
46         void add_effect_raw(Effect *effect, const std::vector<Effect *> &inputs);
47
48         void add_output(const ImageFormat &format);
49         void finalize();
50
51         //void render(unsigned char *src, unsigned char *dst);
52         void render_to_screen();
53
54         Effect *last_added_effect() {
55                 if (effects.empty()) {
56                         return NULL;
57                 } else {
58                         return effects.back();
59                 }       
60         }
61
62 private:
63         struct Phase {
64                 GLint glsl_program_num;
65                 bool input_needs_mipmaps;
66                 std::vector<Effect *> inputs;   // Only from other phases; input textures are not counted here.
67                 std::vector<Effect *> effects;  // In order.
68         };
69
70         void set_use_srgb_texture_format(Effect *effect);
71         Effect *normalize_to_linear_gamma(Effect *input);
72         Effect *normalize_to_srgb(Effect *input);
73
74         void draw_vertex(float x, float y, const std::vector<Effect *> &inputs);
75
76         // Create a GLSL program computing the given effects in order.
77         Phase compile_glsl_program(const std::vector<Effect *> &inputs, const std::vector<Effect *> &effects);
78
79         // Create all GLSL programs needed to compute the given effect, and all outputs
80         // that depends on it (whenever possible).
81         void construct_glsl_programs(Effect *output);
82
83         unsigned width, height;
84         ImageFormat output_format;
85         std::vector<Effect *> effects;
86         std::vector<Input *> inputs;  // Also contained in effects.
87         std::map<Effect *, std::string> effect_ids;
88         std::map<Effect *, GLuint> effect_output_textures;
89         std::map<Effect *, std::vector<Effect *> > outgoing_links;
90         std::map<Effect *, std::vector<Effect *> > incoming_links;
91
92         GLuint fbo;
93         std::vector<Phase> phases;
94
95         GLenum format, bytes_per_pixel;
96         bool finalized;
97
98         // Used during the building of the effect chain.
99         std::map<Effect *, ColorSpace> output_color_space;
100         std::map<Effect *, GammaCurve> output_gamma_curve;      
101 };
102
103
104 #endif // !defined(_EFFECT_CHAIN_H)