+ assert(!inputs.empty());
+ assert(!effects.empty());
+
+ // Figure out the true set of inputs to this phase. These are the ones
+ // that we need somehow but don't calculate ourselves.
+ std::set<Effect *> effect_set(effects.begin(), effects.end());
+ std::set<Effect *> input_set(inputs.begin(), inputs.end());
+ std::vector<Effect *> true_inputs;
+ std::set_difference(input_set.begin(), input_set.end(),
+ effect_set.begin(), effect_set.end(),
+ std::back_inserter(true_inputs));
+
+ bool input_needs_mipmaps = false;
+ std::string frag_shader = read_file("header.frag");
+
+ // Create functions for all the texture inputs that we need.
+ for (unsigned i = 0; i < true_inputs.size(); ++i) {
+ Effect *effect = true_inputs[i];
+ assert(effect_ids.count(effect) != 0);
+ std::string effect_id = effect_ids[effect];
+
+ frag_shader += std::string("uniform sampler2D tex_") + effect_id + ";\n";
+ frag_shader += std::string("vec4 ") + effect_id + "(vec2 tc) {\n";
+ if (effect->num_inputs() == 0) {
+ // OpenGL's origin is bottom-left, but most graphics software assumes
+ // a top-left origin. Thus, for inputs that come from the user,
+ // we flip the y coordinate. However, for FBOs, the origin
+ // is all correct, so don't do anything.
+ frag_shader += "\ttc.y = 1.0f - tc.y;\n";
+ }
+ frag_shader += "\treturn texture2D(tex_" + effect_id + ", tc);\n";
+ frag_shader += "}\n";
+ frag_shader += "\n";
+ }