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];
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.
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;
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;
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);
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);
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.)
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);
}
}
-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();
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