X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=effect_chain.cpp;h=8d030c287a483e72fc7fd7d4898dd1b0cfabd056;hp=471d603079ef201d0d41e2e32c193c8899fbd867;hb=1bd97eb70a6fcb913bf954e369bc1a90ba17f74e;hpb=a6dcad2af7fa40a69b9e4881437cc1dde931c8eb diff --git a/effect_chain.cpp b/effect_chain.cpp index 471d603..8d030c2 100644 --- a/effect_chain.cpp +++ b/effect_chain.cpp @@ -39,6 +39,7 @@ EffectChain::EffectChain(float aspect_nom, float aspect_denom, ResourcePool *res aspect_denom(aspect_denom), dither_effect(NULL), num_dither_bits(0), + output_origin(OUTPUT_ORIGIN_BOTTOM_LEFT), finalized(false), resource_pool(resource_pool), do_phase_timing(false) { @@ -82,13 +83,14 @@ void EffectChain::add_output(const ImageFormat &format, OutputAlphaFormat alpha_ } void EffectChain::add_ycbcr_output(const ImageFormat &format, OutputAlphaFormat alpha_format, - const YCbCrFormat &ycbcr_format) + const YCbCrFormat &ycbcr_format, YCbCrOutputSplitting output_splitting) { assert(!finalized); output_format = format; output_alpha_format = alpha_format; output_color_type = OUTPUT_COLOR_YCBCR; output_ycbcr_format = ycbcr_format; + output_ycbcr_splitting = output_splitting; assert(ycbcr_format.chroma_subsampling_x == 1); assert(ycbcr_format.chroma_subsampling_y == 1); @@ -361,6 +363,23 @@ void EffectChain::compile_glsl_program(Phase *phase) frag_shader += "\n"; } frag_shader += string("#define INPUT ") + phase->effect_ids[phase->effects.back()] + "\n"; + + // If we're the last phase, add the right #defines for Y'CbCr multi-output as needed. + if (phase->output_node->outgoing_links.empty() && output_color_type == OUTPUT_COLOR_YCBCR) { + switch (output_ycbcr_splitting) { + case YCBCR_OUTPUT_INTERLEAVED: + // No #defines set. + break; + case YCBCR_OUTPUT_SPLIT_Y_AND_CBCR: + frag_shader += "#define YCBCR_OUTPUT_SPLIT_Y_AND_CBCR 1\n"; + break; + case YCBCR_OUTPUT_PLANAR: + frag_shader += "#define YCBCR_OUTPUT_PLANAR 1\n"; + break; + default: + assert(false); + } + } frag_shader.append(read_version_dependent_file("footer", "frag")); // Collect uniforms from all effects and output them. Note that this needs @@ -389,6 +408,17 @@ void EffectChain::compile_glsl_program(Phase *phase) frag_shader = frag_shader_header + frag_shader_uniforms + frag_shader; string vert_shader = read_version_dependent_file("vs", "vert"); + + // If we're the last phase and need to flip the picture to compensate for + // the origin, tell the vertex shader so. + if (phase->output_node->outgoing_links.empty() && output_origin == OUTPUT_ORIGIN_TOP_LEFT) { + const string needle = "#define FLIP_ORIGIN 0"; + size_t pos = vert_shader.find(needle); + assert(pos != string::npos); + + vert_shader[pos + needle.size() - 1] = '1'; + } + phase->glsl_program_num = resource_pool->compile_glsl_program(vert_shader, frag_shader); // Collect the resulting location numbers for each uniform. @@ -1625,6 +1655,23 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height glDepthMask(GL_FALSE); check_error(); + // Generate a VAO. All the phases should have exactly the same vertex attributes, + // so it's safe to reuse this. + float vertices[] = { + 0.0f, 2.0f, + 0.0f, 0.0f, + 2.0f, 0.0f + }; + + GLuint vao; + glGenVertexArrays(1, &vao); + check_error(); + glBindVertexArray(vao); + check_error(); + + GLuint position_vbo = fill_vertex_attribute(phases[0]->glsl_program_num, "position", 2, GL_FLOAT, sizeof(vertices), vertices); + GLuint texcoord_vbo = fill_vertex_attribute(phases[0]->glsl_program_num, "texcoord", 2, GL_FLOAT, sizeof(vertices), vertices); // Same as vertices. + set generated_mipmaps; // We choose the simplest option of having one texture per output, @@ -1666,6 +1713,12 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height glUseProgram(0); check_error(); + cleanup_vertex_attribute(phases[0]->glsl_program_num, "position", position_vbo); + cleanup_vertex_attribute(phases[0]->glsl_program_num, "texcoord", texcoord_vbo); + + glDeleteVertexArrays(1, &vao); + check_error(); + if (do_phase_timing) { // Get back the timer queries. for (unsigned phase_num = 0; phase_num < phases.size(); ++phase_num) { @@ -1779,28 +1832,9 @@ void EffectChain::execute_phase(Phase *phase, bool last_phase, maprelease_fbo(fbo); } - - glDeleteVertexArrays(1, &vao); - check_error(); } void EffectChain::setup_uniforms(Phase *phase)