From 5058b68995b5d39042df42df06d55559ee535d38 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Thu, 4 Oct 2012 23:02:15 +0200 Subject: [PATCH] Allow an effect to have multiple inputs (although the graph still supports only one master input). Still no support for it in the processing pipeline. --- blur_effect.cpp | 10 +++++++--- blur_effect.h | 2 +- effect.cpp | 4 ++-- effect.h | 7 ++++++- effect_chain.cpp | 44 ++++++++++++++++++++++++++++++-------------- effect_chain.h | 19 +++++++++++++++---- 6 files changed, 61 insertions(+), 25 deletions(-) diff --git a/blur_effect.cpp b/blur_effect.cpp index 8ffd6dd..2851698 100644 --- a/blur_effect.cpp +++ b/blur_effect.cpp @@ -18,9 +18,13 @@ BlurEffect::BlurEffect() { vpass->set_int("direction", SingleBlurPassEffect::VERTICAL); } -void BlurEffect::add_self_to_effect_chain(EffectChain *chain, Effect *input) { - hpass->add_self_to_effect_chain(chain, input); - vpass->add_self_to_effect_chain(chain, hpass); +void BlurEffect::add_self_to_effect_chain(EffectChain *chain, const std::vector &inputs) { + assert(inputs.size() == 1); + hpass->add_self_to_effect_chain(chain, inputs); + + std::vector vpass_inputs; + vpass_inputs.push_back(hpass); + vpass->add_self_to_effect_chain(chain, vpass_inputs); } bool BlurEffect::set_float(const std::string &key, float value) { diff --git a/blur_effect.h b/blur_effect.h index b47d89b..d90f99a 100644 --- a/blur_effect.h +++ b/blur_effect.h @@ -26,7 +26,7 @@ public: virtual bool needs_texture_bounce() const { return true; } virtual bool needs_mipmaps() const { return true; } - virtual void add_self_to_effect_chain(EffectChain *chain, Effect *input); + virtual void add_self_to_effect_chain(EffectChain *chain, const std::vector &input); virtual bool set_float(const std::string &key, float value); private: diff --git a/effect.cpp b/effect.cpp index 7f8dda2..1aa3778 100644 --- a/effect.cpp +++ b/effect.cpp @@ -170,9 +170,9 @@ void Effect::invalidate_1d_texture(const std::string &key) params_tex_1d[key].needs_update = true; } -void Effect::add_self_to_effect_chain(EffectChain *chain, Effect *input) +void Effect::add_self_to_effect_chain(EffectChain *chain, const std::vector &inputs) { - chain->add_effect_raw(this, input); + chain->add_effect_raw(this, inputs); } // Output convenience uniforms for each parameter. diff --git a/effect.h b/effect.h index 397d364..fcb7526 100644 --- a/effect.h +++ b/effect.h @@ -94,11 +94,16 @@ public: // needs mipmaps, you will also get them). virtual bool needs_mipmaps() const { return false; } + // How many inputs this effect will take (a fixed number). + // If you have only one input, it will be called INPUT() in GLSL; + // if you have several, they will be INPUT1(), INPUT2(), and so on. + virtual unsigned num_inputs() const { return 1; } + // Requests that this effect adds itself to the given effect chain. // For most effects, the default will be fine, but for effects that // consist of multiple passes, it is often useful to replace this // with something that adds completely different things to the chain. - virtual void add_self_to_effect_chain(EffectChain *graph, Effect *input); + virtual void add_self_to_effect_chain(EffectChain *graph, const std::vector &inputs); // Outputs one GLSL uniform declaration for each registered parameter // (see below), with the right prefix prepended to each uniform name. diff --git a/effect_chain.cpp b/effect_chain.cpp index a0e4b5a..fc20ae1 100644 --- a/effect_chain.cpp +++ b/effect_chain.cpp @@ -29,8 +29,8 @@ EffectChain::EffectChain(unsigned width, unsigned height) void EffectChain::add_input(const ImageFormat &format) { input_format = format; - current_color_space = format.color_space; - current_gamma_curve = format.gamma_curve; + output_color_space.insert(std::make_pair(static_cast(NULL), format.color_space)); + output_gamma_curve.insert(std::make_pair(static_cast(NULL), format.gamma_curve)); } void EffectChain::add_output(const ImageFormat &format) @@ -38,11 +38,14 @@ void EffectChain::add_output(const ImageFormat &format) output_format = format; } -void EffectChain::add_effect_raw(Effect *effect, Effect *input) +void EffectChain::add_effect_raw(Effect *effect, const std::vector &inputs) { effects.push_back(effect); - outgoing_links.insert(std::make_pair(input, effect)); - incoming_links.insert(std::make_pair(effect, input)); + assert(inputs.size() == effect->num_inputs()); + for (unsigned i = 0; i < inputs.size(); ++i) { + outgoing_links.insert(std::make_pair(inputs[i], effect)); + incoming_links.insert(std::make_pair(effect, inputs[i])); + } last_added_effect = effect; } @@ -73,6 +76,7 @@ Effect *instantiate_effect(EffectId effect) Effect *EffectChain::normalize_to_linear_gamma(Effect *input) { + GammaCurve current_gamma_curve = output_gamma_curve[input]; if (current_gamma_curve == GAMMA_sRGB) { // TODO: check if the extension exists use_srgb_texture_format = true; @@ -81,7 +85,9 @@ Effect *EffectChain::normalize_to_linear_gamma(Effect *input) } else { GammaExpansionEffect *gamma_conversion = new GammaExpansionEffect(); gamma_conversion->set_int("source_curve", current_gamma_curve); - gamma_conversion->add_self_to_effect_chain(this, input); + std::vector inputs; + inputs.push_back(input); + gamma_conversion->add_self_to_effect_chain(this, inputs); current_gamma_curve = GAMMA_LINEAR; return gamma_conversion; } @@ -89,28 +95,36 @@ Effect *EffectChain::normalize_to_linear_gamma(Effect *input) Effect *EffectChain::normalize_to_srgb(Effect *input) { + GammaCurve current_gamma_curve = output_gamma_curve[input]; + ColorSpace current_color_space = output_color_space[input]; assert(current_gamma_curve == GAMMA_LINEAR); ColorSpaceConversionEffect *colorspace_conversion = new ColorSpaceConversionEffect(); colorspace_conversion->set_int("source_space", current_color_space); colorspace_conversion->set_int("destination_space", COLORSPACE_sRGB); - colorspace_conversion->add_self_to_effect_chain(this, input); + std::vector inputs; + inputs.push_back(input); + colorspace_conversion->add_self_to_effect_chain(this, inputs); current_color_space = COLORSPACE_sRGB; return colorspace_conversion; } -Effect *EffectChain::add_effect(EffectId effect_id, Effect *input) +Effect *EffectChain::add_effect(EffectId effect_id, const std::vector &inputs) { Effect *effect = instantiate_effect(effect_id); - if (effect->needs_linear_light() && current_gamma_curve != GAMMA_LINEAR) { - input = normalize_to_linear_gamma(input); - } + assert(inputs.size() == effect->num_inputs()); - if (effect->needs_srgb_primaries() && current_color_space != COLORSPACE_sRGB) { - input = normalize_to_srgb(input); + std::vector normalized_inputs = inputs; + for (unsigned i = 0; i < normalized_inputs.size(); ++i) { + if (effect->needs_linear_light() && output_gamma_curve[normalized_inputs[i]] != GAMMA_LINEAR) { + normalized_inputs[i] = normalize_to_linear_gamma(normalized_inputs[i]); + } + if (effect->needs_srgb_primaries() && output_color_space[normalized_inputs[i]] != COLORSPACE_sRGB) { + normalized_inputs[i] = normalize_to_srgb(normalized_inputs[i]); + } } - effect->add_self_to_effect_chain(this, input); + effect->add_self_to_effect_chain(this, normalized_inputs); return effect; } @@ -200,6 +214,8 @@ EffectChain::Phase EffectChain::compile_glsl_program(unsigned start_index, unsig void EffectChain::finalize() { // Add normalizers to get the output format right. + GammaCurve current_gamma_curve = output_gamma_curve[last_added_effect]; // FIXME + ColorSpace current_color_space = output_color_space[last_added_effect]; // FIXME if (current_color_space != output_format.color_space) { ColorSpaceConversionEffect *colorspace_conversion = new ColorSpaceConversionEffect(); colorspace_conversion->set_int("source_space", current_color_space); diff --git a/effect_chain.h b/effect_chain.h index a22e96a..f521e9c 100644 --- a/effect_chain.h +++ b/effect_chain.h @@ -41,7 +41,18 @@ public: Effect *add_effect(EffectId effect) { return add_effect(effect, get_last_added_effect()); } - Effect *add_effect(EffectId effect, Effect *input); + Effect *add_effect(EffectId effect, Effect *input) { + std::vector inputs; + inputs.push_back(input); + return add_effect(effect, inputs); + } + Effect *add_effect(EffectId effect, Effect *input1, Effect *input2) { + std::vector inputs; + inputs.push_back(input1); + inputs.push_back(input2); + return add_effect(effect, inputs); + } + Effect *add_effect(EffectId effect, const std::vector &inputs); // Similar to add_effect, but: // @@ -51,7 +62,7 @@ public: // // We should really separate out these two “sides” of Effect in the // type system soon. - void add_effect_raw(Effect *effect, Effect *input); + void add_effect_raw(Effect *effect, const std::vector &inputs); void add_output(const ImageFormat &format); void finalize(); @@ -95,8 +106,8 @@ private: bool finalized; // Used during the building of the effect chain. - ColorSpace current_color_space; - GammaCurve current_gamma_curve; + std::map output_color_space; + std::map output_gamma_curve; }; -- 2.39.2