#include <stdio.h>
#include <math.h>
#include <string.h>
+#include <locale.h>
#include <assert.h>
#include <GL/glew.h>
// without any explicit recursion.
void EffectChain::construct_glsl_programs(Node *output)
{
- // Which effects have already been completed in this phase?
+ // Which effects have already been completed?
// We need to keep track of it, as an effect with multiple outputs
// could otherwise be calculated multiple times.
std::set<Node *> completed_effects;
// This should currently only happen for effects that are inputs
// (either true inputs or phase outputs). We special-case inputs,
// and then deduplicate phase outputs in compile_glsl_program().
- if (node->effect->num_inputs() == 0 && completed_effects.count(node)) {
- continue;
+ if (node->effect->num_inputs() == 0) {
+ if (find(this_phase_effects.begin(), this_phase_effects.end(), node) != this_phase_effects.end()) {
+ continue;
+ }
+ } else {
+ assert(completed_effects.count(node) == 0);
}
- assert(completed_effects.count(node) == 0);
this_phase_effects.push_back(node);
completed_effects.insert(node);
}
// Go through each input that is not sRGB, and insert
- // a colorspace conversion before it.
+ // a colorspace conversion after it.
for (unsigned j = 0; j < node->incoming_links.size(); ++j) {
Node *input = node->incoming_links[j];
assert(input->output_color_space != COLORSPACE_INVALID);
CHECK(conversion->effect->set_int("source_space", input->output_color_space));
CHECK(conversion->effect->set_int("destination_space", COLORSPACE_sRGB));
conversion->output_color_space = COLORSPACE_sRGB;
- insert_node_between(input, conversion, node);
+ replace_sender(input, conversion);
+ connect_nodes(input, conversion);
}
// Re-sort topologically, and propagate the new information.
conversion = add_node(new AlphaDivisionEffect());
}
conversion->output_alpha_type = desired_type;
- insert_node_between(input, conversion, node);
+ replace_sender(input, conversion);
+ connect_nodes(input, conversion);
}
// Re-sort topologically, and propagate the new information.
}
// If not, go through each input that is not linear gamma,
- // and insert a gamma conversion before it.
+ // and insert a gamma conversion after it.
for (unsigned j = 0; j < node->incoming_links.size(); ++j) {
Node *input = node->incoming_links[j];
assert(input->output_gamma_curve != GAMMA_INVALID);
Node *conversion = add_node(new GammaExpansionEffect());
CHECK(conversion->effect->set_int("source_curve", input->output_gamma_curve));
conversion->output_gamma_curve = GAMMA_LINEAR;
- insert_node_between(input, conversion, node);
+ replace_sender(input, conversion);
+ connect_nodes(input, conversion);
}
// Re-sort topologically, and propagate the new information.
void EffectChain::finalize()
{
+ // Save the current locale, and set it to C, so that we can output decimal
+ // numbers with printf and be sure to get them in the format mandated by GLSL.
+ char *saved_locale = setlocale(LC_NUMERIC, "C");
+
// Output the graph as it is before we do any conversions on it.
output_dot("step0-start.dot");
assert(phases[0]->inputs.empty());
finalized = true;
+ setlocale(LC_NUMERIC, saved_locale);
}
void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height)