Handle sampler2D uniforms specially.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 13 Sep 2015 18:15:29 +0000 (20:15 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 13 Sep 2015 18:21:44 +0000 (20:21 +0200)
We're going to need this soon, since sampler uniforms are special
in that they cannot be in a uniform block.

effect.cpp
effect.h
effect_chain.cpp
effect_chain.h

index df73eea..060bf7d 100644 (file)
@@ -95,34 +95,34 @@ void Effect::set_gl_state(GLuint glsl_program_num, const string& prefix, unsigne
 
 void Effect::clear_gl_state() {}
 
-void Effect::register_uniform_bool(const std::string &key, const bool *value)
+void Effect::register_uniform_sampler2d(const std::string &key, const GLint *value)
 {
-       Uniform<bool> uniform;
+       Uniform<int> uniform;
        uniform.name = key;
        uniform.value = value;
        uniform.num_values = 1;
        uniform.location = -1;
-       uniforms_bool.push_back(uniform);
+       uniforms_sampler2d.push_back(uniform);
 }
 
-void Effect::register_uniform_int(const std::string &key, const int *value)
+void Effect::register_uniform_bool(const std::string &key, const bool *value)
 {
-       Uniform<int> uniform;
+       Uniform<bool> uniform;
        uniform.name = key;
        uniform.value = value;
        uniform.num_values = 1;
        uniform.location = -1;
-       uniforms_int.push_back(uniform);
+       uniforms_bool.push_back(uniform);
 }
 
-void Effect::register_uniform_sampler2d(const std::string &key, const GLint *value)
+void Effect::register_uniform_int(const std::string &key, const int *value)
 {
        Uniform<int> uniform;
        uniform.name = key;
        uniform.value = value;
        uniform.num_values = 1;
        uniform.location = -1;
-       uniforms_sampler2d.push_back(uniform);
+       uniforms_int.push_back(uniform);
 }
 
 void Effect::register_uniform_float(const std::string &key, const float *value)
index 9d81a56..6154dac 100644 (file)
--- a/effect.h
+++ b/effect.h
@@ -332,9 +332,9 @@ protected:
        //
        // Calling register_* will automatically imply register_uniform_*,
        // except for register_int as noted above.
+       void register_uniform_sampler2d(const std::string &key, const int *value);
        void register_uniform_bool(const std::string &key, const bool *value);
        void register_uniform_int(const std::string &key, const int *value);  // Note: Requires GLSL 1.30 or newer.
-       void register_uniform_sampler2d(const std::string &key, const int *value);
        void register_uniform_float(const std::string &key, const float *value);
        void register_uniform_vec2(const std::string &key, const float *values);
        void register_uniform_vec3(const std::string &key, const float *values);
@@ -351,9 +351,9 @@ private:
        std::map<std::string, float *> params_vec4;
 
        // Picked out by EffectChain during finalization.
+       std::vector<Uniform<int> > uniforms_sampler2d;
        std::vector<Uniform<bool> > uniforms_bool;
        std::vector<Uniform<int> > uniforms_int;
-       std::vector<Uniform<int> > uniforms_sampler2d;
        std::vector<Uniform<float> > uniforms_float;
        std::vector<Uniform<float> > uniforms_vec2;
        std::vector<Uniform<float> > uniforms_vec3;
index 6e297df..4460614 100644 (file)
@@ -317,6 +317,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 +335,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 +391,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);
@@ -1835,6 +1839,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);
index ee4c7ba..8bceaee 100644 (file)
@@ -117,6 +117,7 @@ struct Phase {
        std::map<Node *, std::string> effect_ids;
 
        // Uniforms for this phase; combined from all the effects.
+       std::vector<Uniform<int> > uniforms_sampler2d;
        std::vector<Uniform<bool> > uniforms_bool;
        std::vector<Uniform<int> > uniforms_int;
        std::vector<Uniform<float> > uniforms_float;