X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=effect_chain.cpp;h=0cd480287e5672eb0f09812535153ac500697d02;hp=c803c62b795a5160deccbc5c2e0fb7dc050fc638;hb=56ff92c5828a143595eeb7a1906418cc30668f9d;hpb=f420ba91b26aad7701f781bf371f47662a19f452 diff --git a/effect_chain.cpp b/effect_chain.cpp index c803c62..0cd4802 100644 --- a/effect_chain.cpp +++ b/effect_chain.cpp @@ -1,6 +1,6 @@ #define GL_GLEXT_PROTOTYPES 1 -#include +#include #include #include #include @@ -359,13 +359,13 @@ void EffectChain::construct_glsl_programs(Node *output) for (unsigned i = 0; i < deps.size(); ++i) { bool start_new_phase = false; - // FIXME: If we sample directly from a texture, we won't need this. - if (node->effect->needs_texture_bounce()) { + if (node->effect->needs_texture_bounce() && + !deps[i]->effect->is_single_texture()) { start_new_phase = true; } if (deps[i]->outgoing_links.size() > 1) { - if (deps[i]->effect->num_inputs() > 0) { + if (!deps[i]->effect->is_single_texture()) { // More than one effect uses this as the input, // and it is not a texture itself. // The easiest thing to do (and probably also the safest @@ -373,6 +373,8 @@ void EffectChain::construct_glsl_programs(Node *output) // and then let the next passes read from that. start_new_phase = true; } else { + assert(deps[i]->effect->num_inputs() == 0); + // For textures, we try to be slightly more clever; // if none of our outputs need a bounce, we don't bounce // but instead simply use the effect many times. @@ -1470,6 +1472,7 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height } const GLuint glsl_program_num = phases[phase]->glsl_program_num; + check_error(); glUseProgram(glsl_program_num); check_error(); @@ -1536,43 +1539,37 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height // Now draw! float vertices[] = { + 0.0f, 1.0f, 0.0f, 0.0f, - 1.0f, 0.0f, 1.0f, 1.0f, - 0.0f, 1.0f + 1.0f, 0.0f }; - int position_attrib = glGetAttribLocation(glsl_program_num, "position"); - assert(position_attrib != -1); - glEnableVertexAttribArray(position_attrib); + GLuint vao; + glGenVertexArrays(1, &vao); check_error(); - glVertexAttribPointer(position_attrib, 2, GL_FLOAT, GL_FALSE, 0, vertices); + glBindVertexArray(vao); check_error(); - int texcoord_attrib = glGetAttribLocation(glsl_program_num, "texcoord"); - if (texcoord_attrib != -1) { - glEnableVertexAttribArray(texcoord_attrib); - check_error(); - glVertexAttribPointer(texcoord_attrib, 2, GL_FLOAT, GL_FALSE, 0, vertices); // Same as texcoords. - check_error(); - } + GLuint position_vbo = fill_vertex_attribute(glsl_program_num, "position", 2, GL_FLOAT, sizeof(vertices), vertices); + GLuint texcoord_vbo = fill_vertex_attribute(glsl_program_num, "texcoord", 2, GL_FLOAT, sizeof(vertices), vertices); // Same as vertices. - glDrawArrays(GL_QUADS, 0, 4); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); check_error(); + cleanup_vertex_attribute(glsl_program_num, "position", position_vbo); + cleanup_vertex_attribute(glsl_program_num, "texcoord", texcoord_vbo); + glUseProgram(0); check_error(); - glDisableVertexAttribArray(position_attrib); - check_error(); - if (texcoord_attrib != -1) { - glDisableVertexAttribArray(texcoord_attrib); - check_error(); - } for (unsigned i = 0; i < phases[phase]->effects.size(); ++i) { Node *node = phases[phase]->effects[i]; node->effect->clear_gl_state(); } + + glDeleteVertexArrays(1, &vao); + check_error(); } for (map::const_iterator texture_it = output_textures.begin();