namespace movit {
-EffectChain::EffectChain(float aspect_nom, float aspect_denom, ResourcePool *resource_pool, GLenum intermediate_format)
+EffectChain::EffectChain(float aspect_nom, float aspect_denom, ResourcePool *resource_pool)
: aspect_nom(aspect_nom),
aspect_denom(aspect_denom),
output_color_rgba(false),
output_color_ycbcr(false),
dither_effect(NULL),
- intermediate_format(intermediate_format),
+ intermediate_format(GL_RGBA16F),
+ intermediate_transformation(NO_FRAMEBUFFER_TRANSFORMATION),
num_dither_bits(0),
output_origin(OUTPUT_ORIGIN_BOTTOM_LEFT),
finalized(false),
frag_shader += string("uniform sampler2D tex_") + effect_id + ";\n";
frag_shader += string("vec4 ") + effect_id + "(vec2 tc) {\n";
- frag_shader += "\treturn tex2D(tex_" + string(effect_id) + ", tc);\n";
+ frag_shader += "\tvec4 tmp = tex2D(tex_" + string(effect_id) + ", tc);\n";
+
+ if (intermediate_transformation == SQUARE_ROOT_FRAMEBUFFER_TRANSFORMATION &&
+ phase->inputs[i]->output_node->output_gamma_curve == GAMMA_LINEAR) {
+ frag_shader += "\ttmp.rgb *= tmp.rgb;\n";
+ }
+
+ frag_shader += "\treturn tmp;\n";
frag_shader += "}\n";
frag_shader += "\n";
frag_shader_outputs.push_back("RGBA");
}
}
+
+ // If we're bouncing to a temporary texture, signal transformation if desired.
+ if (!phase->output_node->outgoing_links.empty()) {
+ if (intermediate_transformation == SQUARE_ROOT_FRAMEBUFFER_TRANSFORMATION &&
+ phase->output_node->output_gamma_curve == GAMMA_LINEAR) {
+ frag_shader += "#define SQUARE_ROOT_TRANSFORMATION 1\n";
+ }
+ }
+
frag_shader.append(read_file("footer.frag"));
// Collect uniforms from all effects and output them. Note that this needs
if (alpha_handling == Effect::INPUT_AND_OUTPUT_PREMULTIPLIED_ALPHA ||
alpha_handling == Effect::INPUT_PREMULTIPLIED_ALPHA_KEEP_BLANK) {
+ // This combination (requiring premultiplied alpha, but _not_ requiring
+ // linear light) is illegal, since the combination of premultiplied alpha
+ // and nonlinear inputs is meaningless.
+ assert(node->effect->needs_linear_light());
+
// If the effect has asked for premultiplied alpha, check that it has got it.
if (any_postmultiplied) {
node->output_alpha_type = ALPHA_INVALID;
output_textures->insert(make_pair(phase, tex_num));
}
- glUseProgram(phase->glsl_program_num);
- check_error();
-
// Set up RTT inputs for this phase.
for (unsigned sampler = 0; sampler < phase->inputs.size(); ++sampler) {
glActiveTexture(GL_TEXTURE0 + sampler);
glViewport(0, 0, phase->output_width, phase->output_height);
}
+ GLuint instance_program_num = resource_pool->use_glsl_program(phase->glsl_program_num);
+ check_error();
+
// Give the required parameters to all the effects.
unsigned sampler_num = phase->inputs.size();
for (unsigned i = 0; i < phase->effects.size(); ++i) {
Node *node = phase->effects[i];
unsigned old_sampler_num = sampler_num;
- node->effect->set_gl_state(phase->glsl_program_num, phase->effect_ids[node], &sampler_num);
+ node->effect->set_gl_state(instance_program_num, phase->effect_ids[node], &sampler_num);
check_error();
if (node->effect->is_single_texture()) {
node->effect->clear_gl_state();
}
+ resource_pool->unuse_glsl_program(instance_program_num);
+
if (!last_phase) {
resource_pool->release_fbo(fbo);
}