Handle texture non-bounce a bit better.
[movit] / effect_chain.cpp
index c803c62..0cd4802 100644 (file)
@@ -1,6 +1,6 @@
 #define GL_GLEXT_PROTOTYPES 1
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <locale.h>
 #include <math.h>
@@ -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<Phase *, GLuint>::const_iterator texture_it = output_textures.begin();