]> git.sesse.net Git - movit/blobdiff - effect_chain.cpp
Cleanup: Make uniforms for RTT samplers like all other uniforms.
[movit] / effect_chain.cpp
index 6e297dfeb49d44f7d0044f0c2cb46ef4eacbd6d2..4e3f322bfe68cc5a68f2530ac1b5a5ef8a0d285f 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.
@@ -317,6 +325,12 @@ void EffectChain::compile_glsl_program(Phase *phase)
                Node *node = phase->effects[i];
                Effect *effect = node->effect;
                const string effect_id = phase->effect_ids[node];
+               for (unsigned j = 0; j < effect->uniforms_sampler2d.size(); ++j) {
+                       phase->uniforms_sampler2d.push_back(effect->uniforms_sampler2d[j]);
+                       phase->uniforms_sampler2d.back().prefix = effect_id;
+                       frag_shader_uniforms += string("uniform sampler2D ") + effect_id
+                               + "_" + effect->uniforms_sampler2d[j].name + ";\n";
+               }
                for (unsigned j = 0; j < effect->uniforms_bool.size(); ++j) {
                        phase->uniforms_bool.push_back(effect->uniforms_bool[j]);
                        phase->uniforms_bool.back().prefix = effect_id;
@@ -329,12 +343,6 @@ void EffectChain::compile_glsl_program(Phase *phase)
                        frag_shader_uniforms += string("uniform int ") + effect_id
                                + "_" + effect->uniforms_int[j].name + ";\n";
                }
-               for (unsigned j = 0; j < effect->uniforms_sampler2d.size(); ++j) {
-                       phase->uniforms_int.push_back(effect->uniforms_sampler2d[j]);
-                       phase->uniforms_int.back().prefix = effect_id;
-                       frag_shader_uniforms += string("uniform sampler2D ") + effect_id
-                               + "_" + effect->uniforms_sampler2d[j].name + ";\n";
-               }
                for (unsigned j = 0; j < effect->uniforms_float.size(); ++j) {
                        phase->uniforms_float.push_back(effect->uniforms_float[j]);
                        phase->uniforms_float.back().prefix = effect_id;
@@ -391,6 +399,10 @@ void EffectChain::compile_glsl_program(Phase *phase)
        phase->glsl_program_num = resource_pool->compile_glsl_program(vert_shader, frag_shader);
 
        // Collect the resulting program numbers for each uniform.
+       for (unsigned i = 0; i < phase->uniforms_sampler2d.size(); ++i) {
+               Uniform<int> &uniform = phase->uniforms_sampler2d[i];
+               uniform.location = get_uniform_location(phase->glsl_program_num, uniform.prefix, uniform.name);
+       }
        for (unsigned i = 0; i < phase->uniforms_bool.size(); ++i) {
                Uniform<bool> &uniform = phase->uniforms_bool[i];
                uniform.location = get_uniform_location(phase->glsl_program_num, uniform.prefix, uniform.name);
@@ -553,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);
@@ -1764,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.)
@@ -1835,6 +1851,12 @@ void EffectChain::execute_phase(Phase *phase, bool last_phase, map<Phase *, GLui
 void EffectChain::setup_uniforms(Phase *phase)
 {
        // TODO: Use UBO blocks.
+       for (size_t i = 0; i < phase->uniforms_sampler2d.size(); ++i) {
+               const Uniform<int> &uniform = phase->uniforms_sampler2d[i];
+               if (uniform.location != -1) {
+                       glUniform1iv(uniform.location, uniform.num_values, uniform.value);
+               }
+       }
        for (size_t i = 0; i < phase->uniforms_bool.size(); ++i) {
                const Uniform<bool> &uniform = phase->uniforms_bool[i];
                assert(uniform.num_values == 1);
@@ -1888,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();
@@ -1903,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