X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=complex_modulate_effect.h;fp=complex_modulate_effect.h;h=52de229b915eadeb153f177630ea554076f257f3;hp=0000000000000000000000000000000000000000;hb=860d514c63758cb91eb301ce4dc08bb984a835b0;hpb=e9f0fb5e6ae193a5a853ac5aef82927b6a81267a diff --git a/complex_modulate_effect.h b/complex_modulate_effect.h new file mode 100644 index 0000000..52de229 --- /dev/null +++ b/complex_modulate_effect.h @@ -0,0 +1,61 @@ +#ifndef _MOVIT_COMPLEX_MODULATE_EFFECT_H +#define _MOVIT_COMPLEX_MODULATE_EFFECT_H 1 + +// An effect that treats each pixel as two complex numbers (xy and zw), +// and multiplies it with some other complex number (xy and xy, so the +// same in both cases). The latter can be repeated both horizontally and +// vertically if desired. +// +// The typical use is to implement convolution by way of FFT; since +// FFT(A ⊙ B) = FFT(A) * FFT(B), you can FFT both inputs (where B +// would often even be a constant, so you'd only need to do FFT once), +// multiply them together and then IFFT the result to get a convolution. +// +// It is in a sense “wrong” to do this directly on pixels, since the color +// channels are independent and real-valued (ie., not complex numbers), but +// since convolution is a linear operation, it's unproblematic to treat R + Gi +// as a single complex number and B + Ai and another one; barring numerical +// errors, there should be no leakage between the channels as long as you're +// convolving with a real quantity. (There are more sophisticated ways of doing +// two real FFTs with a single complex one, but we won't need them, as we +// don't care about the actual FFT result, just that the convolution property +// holds.) + +#include +#include + +#include "effect.h" + +namespace movit { + +class EffectChain; + +class ComplexModulateEffect : public Effect { +public: + ComplexModulateEffect(); + virtual std::string effect_type_id() const { return "ComplexModulateEffect"; } + std::string output_fragment_shader(); + + // Technically we only need texture bounce for the second input + // (to be allowed to mess with its sampler state), but there's + // no way of expressing that currently. + virtual bool needs_texture_bounce() const { return true; } + virtual bool changes_output_size() const { return true; } + + virtual void inform_input_size(unsigned input_num, unsigned width, unsigned height); + virtual void get_output_size(unsigned *width, unsigned *height, + unsigned *virtual_width, unsigned *virtual_height) const; + virtual unsigned num_inputs() const { return 2; } + virtual void inform_added(EffectChain *chain) { this->chain = chain; } + + void set_gl_state(GLuint glsl_program_num, const std::string &prefix, unsigned *sampler_num); + +private: + EffectChain *chain; + int primary_input_width, primary_input_height; + int num_repeats_x, num_repeats_y; +}; + +} // namespace movit + +#endif // !defined(_MOVIT_COMPLEX_MODULATE_EFFECT_H)