]> git.sesse.net Git - movit/blobdiff - effect_chain.cpp
Add support for multiple shader models.
[movit] / effect_chain.cpp
index 8d3c61d27f4293eed70e9b5dfd4b02e6af9e9bbf..82f1b2939cc088e8268c0d883f6a1c69e0979dc1 100644 (file)
@@ -1,6 +1,6 @@
 #define GL_GLEXT_PROTOTYPES 1
 
 #define GL_GLEXT_PROTOTYPES 1
 
-#include <GL/glew.h>
+#include <epoxy/gl.h>
 #include <assert.h>
 #include <locale.h>
 #include <math.h>
 #include <assert.h>
 #include <locale.h>
 #include <math.h>
@@ -53,6 +53,15 @@ EffectChain::~EffectChain()
                delete nodes[i];
        }
        for (unsigned i = 0; i < phases.size(); ++i) {
                delete nodes[i];
        }
        for (unsigned i = 0; i < phases.size(); ++i) {
+               glBindVertexArray(phases[i]->vao);
+               check_error();
+
+               cleanup_vertex_attribute(phases[i]->glsl_program_num, "position", phases[i]->position_vbo);
+               cleanup_vertex_attribute(phases[i]->glsl_program_num, "texcoord", phases[i]->texcoord_vbo);
+
+               glBindVertexArray(0);
+               check_error();
+
                resource_pool->release_glsl_program(phases[i]->glsl_program_num);
                delete phases[i];
        }
                resource_pool->release_glsl_program(phases[i]->glsl_program_num);
                delete phases[i];
        }
@@ -234,7 +243,7 @@ string replace_prefix(const string &text, const string &prefix)
 
 void EffectChain::compile_glsl_program(Phase *phase)
 {
 
 void EffectChain::compile_glsl_program(Phase *phase)
 {
-       string frag_shader = read_file("header.frag");
+       string frag_shader = read_version_dependent_file("header", "frag");
 
        // Create functions for all the texture inputs that we need.
        for (unsigned i = 0; i < phase->inputs.size(); ++i) {
 
        // Create functions for all the texture inputs that we need.
        for (unsigned i = 0; i < phase->inputs.size(); ++i) {
@@ -245,7 +254,7 @@ void EffectChain::compile_glsl_program(Phase *phase)
        
                frag_shader += string("uniform sampler2D tex_") + effect_id + ";\n";
                frag_shader += string("vec4 ") + effect_id + "(vec2 tc) {\n";
        
                frag_shader += string("uniform sampler2D tex_") + effect_id + ";\n";
                frag_shader += string("vec4 ") + effect_id + "(vec2 tc) {\n";
-               frag_shader += "\treturn texture2D(tex_" + string(effect_id) + ", tc);\n";
+               frag_shader += "\treturn tex2D(tex_" + string(effect_id) + ", tc);\n";
                frag_shader += "}\n";
                frag_shader += "\n";
        }
                frag_shader += "}\n";
                frag_shader += "\n";
        }
@@ -284,9 +293,31 @@ void EffectChain::compile_glsl_program(Phase *phase)
                frag_shader += "\n";
        }
        frag_shader += string("#define INPUT ") + phase->effect_ids[phase->effects.back()] + "\n";
                frag_shader += "\n";
        }
        frag_shader += string("#define INPUT ") + phase->effect_ids[phase->effects.back()] + "\n";
-       frag_shader.append(read_file("footer.frag"));
+       frag_shader.append(read_version_dependent_file("footer", "frag"));
+
+       string vert_shader = read_version_dependent_file("vs", "vert");
+       phase->glsl_program_num = resource_pool->compile_glsl_program(vert_shader, frag_shader);
+
+       // Prepare the geometry for the fullscreen quad used in this phase.
+       // (We have separate VAOs per shader, since the bindings can in theory
+       // be different.)
+       float vertices[] = {
+               0.0f, 1.0f,
+               0.0f, 0.0f,
+               1.0f, 1.0f,
+               1.0f, 0.0f
+       };
+
+       glGenVertexArrays(1, &phase->vao);
+       check_error();
+       glBindVertexArray(phase->vao);
+       check_error();
+
+       phase->position_vbo = fill_vertex_attribute(phase->glsl_program_num, "position", 2, GL_FLOAT, sizeof(vertices), vertices);
+       phase->texcoord_vbo = fill_vertex_attribute(phase->glsl_program_num, "texcoord", 2, GL_FLOAT, sizeof(vertices), vertices);  // Same as vertices.
 
 
-       phase->glsl_program_num = resource_pool->compile_glsl_program(read_file("vs.vert"), frag_shader);
+       glBindVertexArray(0);
+       check_error();
 }
 
 // Construct GLSL programs, starting at the given effect and following
 }
 
 // Construct GLSL programs, starting at the given effect and following
@@ -1532,39 +1563,15 @@ 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, 1.0f,
-                       1.0f, 0.0f
-               };
-
-               GLuint vao;
-               glGenVertexArrays(1, &vao);
+               glBindVertexArray(phases[phase]->vao);
                check_error();
                check_error();
-               glBindVertexArray(vao);
-               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_TRIANGLE_STRIP, 0, 4);
                check_error();
 
                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();
-
                for (unsigned i = 0; i < phases[phase]->effects.size(); ++i) {
                        Node *node = phases[phase]->effects[i];
                        node->effect->clear_gl_state();
                }
                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();
        }
 
        for (map<Phase *, GLuint>::const_iterator texture_it = output_textures.begin();
@@ -1575,6 +1582,10 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height
 
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        check_error();
 
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        check_error();
+       glBindVertexArray(0);
+       check_error();
+       glUseProgram(0);
+       check_error();
 }
 
 }  // namespace movit
 }
 
 }  // namespace movit