Cleanup: Make uniforms for RTT samplers like all other uniforms.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 13 Sep 2015 18:40:58 +0000 (20:40 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 13 Sep 2015 18:40:58 +0000 (20:40 +0200)
This also removes an ugly special-casing where one single place
in the entire code would call glUniform1i directly.

effect_chain.cpp
effect_chain.h

index 4460614..4e3f322 100644 (file)
@@ -252,7 +252,7 @@ void EffectChain::compile_glsl_program(Phase *phase)
        string frag_shader_header = read_version_dependent_file("header", "frag");
        string frag_shader = "";
 
-       // Create functions for all the texture inputs that we need.
+       // Create functions and uniforms for all the texture inputs that we need.
        for (unsigned i = 0; i < phase->inputs.size(); ++i) {
                Node *input = phase->inputs[i]->output_node;
                char effect_id[256];
@@ -264,6 +264,14 @@ void EffectChain::compile_glsl_program(Phase *phase)
                frag_shader += "\treturn tex2D(tex_" + string(effect_id) + ", tc);\n";
                frag_shader += "}\n";
                frag_shader += "\n";
+
+               Uniform<int> uniform;
+               uniform.name = effect_id;
+               uniform.value = &phase->input_samplers[i];
+               uniform.prefix = "tex";
+               uniform.num_values = 1;
+               uniform.location = -1;
+               phase->uniforms_sampler2d.push_back(uniform);
        }
 
        // Give each effect in the phase its own ID.
@@ -557,6 +565,9 @@ Phase *EffectChain::construct_phase(Node *output, map<Node *, Phase *> *complete
        sort(phase->inputs.begin(), phase->inputs.end());
        phase->inputs.erase(unique(phase->inputs.begin(), phase->inputs.end()), phase->inputs.end());
 
+       // Allocate samplers for each input.
+       phase->input_samplers.resize(phase->inputs.size());
+
        // We added the effects from the output and back, but we need to output
        // them in topological sort order in the shader.
        phase->effects = topological_sort(phase->effects);
@@ -1768,7 +1779,8 @@ void EffectChain::execute_phase(Phase *phase, bool last_phase, map<Phase *, GLui
                        check_error();
                        generated_mipmaps->insert(input);
                }
-               setup_rtt_sampler(glsl_program_num, sampler, phase->effect_ids[input->output_node], phase->input_needs_mipmaps);
+               setup_rtt_sampler(sampler, phase->input_needs_mipmaps);
+               phase->input_samplers[sampler] = sampler;  // Bind the sampler to the right uniform.
        }
 
        // And now the output. (Already set up for us if it is the last phase.)
@@ -1898,7 +1910,7 @@ void EffectChain::setup_uniforms(Phase *phase)
        }
 }
 
-void EffectChain::setup_rtt_sampler(GLuint glsl_program_num, int sampler_num, const string &effect_id, bool use_mipmaps)
+void EffectChain::setup_rtt_sampler(int sampler_num, bool use_mipmaps)
 {
        glActiveTexture(GL_TEXTURE0 + sampler_num);
        check_error();
@@ -1913,10 +1925,6 @@ void EffectChain::setup_rtt_sampler(GLuint glsl_program_num, int sampler_num, co
        check_error();
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        check_error();
-
-       string texture_name = string("tex_") + effect_id;
-       glUniform1i(glGetUniformLocation(glsl_program_num, texture_name.c_str()), sampler_num);
-       check_error();
 }
 
 }  // namespace movit
index 8bceaee..1be9891 100644 (file)
@@ -109,6 +109,10 @@ struct Phase {
        // Inputs are only inputs from other phases (ie., those that come from RTT);
        // input textures are counted as part of <effects>.
        std::vector<Phase *> inputs;
+       // Bound sampler numbers for each input. Redundant in a sense
+       // (it always corresponds to the index), but we need somewhere
+       // to hold the value for the uniform.
+       std::vector<int> input_samplers;
        std::vector<Node *> effects;  // In order.
        unsigned output_width, output_height, virtual_output_width, virtual_output_height;
 
@@ -280,9 +284,8 @@ private:
        // Set up uniforms for one phase. The program must already be bound.
        void setup_uniforms(Phase *phase);
 
-       // Set up the given sampler number for sampling from an RTT texture,
-       // and bind it to "tex_" plus the given GLSL variable.
-       void setup_rtt_sampler(GLuint glsl_program_num, int sampler_num, const std::string &effect_id, bool use_mipmaps);
+       // Set up the given sampler number for sampling from an RTT texture.
+       void setup_rtt_sampler(int sampler_num, bool use_mipmaps);
 
        // Output the current graph to the given file in a Graphviz-compatible format;
        // only useful for debugging.