]> git.sesse.net Git - movit/commitdiff
Merge branch 'master' into epoxy
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 22 Mar 2014 14:53:11 +0000 (15:53 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 22 Mar 2014 14:53:11 +0000 (15:53 +0100)
1  2 
effect_chain.cpp
effect_chain.h

diff --combined effect_chain.cpp
index 47938455b02bee9f9ff1b1be7b3cf5cbe1fd0a95,e4ab7199c8d23320c545d47c98b4c53dec39af3b..7bce60fa21c1e076c3082d69ff2e409cc342750a
@@@ -1,6 -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>
@@@ -238,7 -238,7 +238,7 @@@ string replace_prefix(const string &tex
  
  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) {
        
                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 += 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"));
  
 -      phase->glsl_program_num = resource_pool->compile_glsl_program(read_file("vs.vert"), frag_shader);
 +      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
@@@ -1435,8 -1434,6 +1435,6 @@@ void EffectChain::render_to_fbo(GLuint 
  
        // Save original viewport.
        GLuint x = 0, y = 0;
-       GLuint fbo = 0;
-       void *context = get_gl_context_identifier();
  
        if (width == 0 && height == 0) {
                GLint viewport[4];
        for (unsigned phase_num = 0; phase_num < phases.size(); ++phase_num) {
                Phase *phase = phases[phase_num];
  
-               // Find a texture for this phase.
-               inform_input_sizes(phase);
-               if (phase_num != phases.size() - 1) {
-                       find_output_size(phase);
-                       GLuint tex_num = resource_pool->create_2d_texture(GL_RGBA16F, phase->output_width, phase->output_height);
-                       output_textures.insert(make_pair(phase, tex_num));
-               }
-               const GLuint glsl_program_num = phase->glsl_program_num;
-               check_error();
-               glUseProgram(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);
-                       Phase *input = phase->inputs[sampler];
-                       input->output_node->bound_sampler_num = sampler;
-                       glBindTexture(GL_TEXTURE_2D, output_textures[input]);
-                       check_error();
-                       if (phase->input_needs_mipmaps) {
-                               if (generated_mipmaps.count(input) == 0) {
-                                       glGenerateMipmap(GL_TEXTURE_2D);
-                                       check_error();
-                                       generated_mipmaps.insert(input);
-                               }
-                               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
-                               check_error();
-                       } else {
-                               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-                               check_error();
-                       }
-                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-                       check_error();
-                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-                       check_error();
-                       string texture_name = string("tex_") + phase->effect_ids[input->output_node];
-                       glUniform1i(glGetUniformLocation(glsl_program_num, texture_name.c_str()), sampler);
-                       check_error();
-               }
-               // And now the output.
                if (phase_num == phases.size() - 1) {
                        // Last phase goes to the output the user specified.
                        glBindFramebuffer(GL_FRAMEBUFFER, dest_fbo);
                                CHECK(dither_effect->set_int("output_width", width));
                                CHECK(dither_effect->set_int("output_height", height));
                        }
-               } else {
-                       fbo = resource_pool->create_fbo(context, output_textures[phase]);
-                       glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-                       glViewport(0, 0, phase->output_width, phase->output_height);
-               }
-               // 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(glsl_program_num, phase->effect_ids[node], &sampler_num);
-                       check_error();
-                       if (node->effect->is_single_texture()) {
-                               assert(sampler_num - old_sampler_num == 1);
-                               node->bound_sampler_num = old_sampler_num;
-                       } else {
-                               node->bound_sampler_num = -1;
-                       }
-               }
-               glBindVertexArray(phase->vao);
-               check_error();
-               glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-               check_error();
-               for (unsigned i = 0; i < phase->effects.size(); ++i) {
-                       Node *node = phase->effects[i];
-                       node->effect->clear_gl_state();
-               }
-               if (phase_num != phases.size() - 1) {
-                       resource_pool->release_fbo(fbo);
                }
+               execute_phase(phase, phase_num == phases.size() - 1, &output_textures, &generated_mipmaps);
        }
  
        for (map<Phase *, GLuint>::const_iterator texture_it = output_textures.begin();
        check_error();
  }
  
+ void EffectChain::execute_phase(Phase *phase, bool last_phase, map<Phase *, GLuint> *output_textures, set<Phase *> *generated_mipmaps)
+ {
+       GLuint fbo = 0;
+       // Find a texture for this phase.
+       inform_input_sizes(phase);
+       if (!last_phase) {
+               find_output_size(phase);
+               GLuint tex_num = resource_pool->create_2d_texture(GL_RGBA16F, phase->output_width, phase->output_height);
+               output_textures->insert(make_pair(phase, tex_num));
+       }
+       const GLuint glsl_program_num = phase->glsl_program_num;
+       check_error();
+       glUseProgram(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);
+               Phase *input = phase->inputs[sampler];
+               input->output_node->bound_sampler_num = sampler;
+               glBindTexture(GL_TEXTURE_2D, (*output_textures)[input]);
+               check_error();
+               if (phase->input_needs_mipmaps && generated_mipmaps->count(input) == 0) {
+                       glGenerateMipmap(GL_TEXTURE_2D);
+                       check_error();
+                       generated_mipmaps->insert(input);
+               }
+               setup_rtt_sampler(glsl_program_num, sampler, phase->effect_ids[input->output_node], phase->input_needs_mipmaps);
+       }
+       // And now the output. (Already set up for us if it is the last phase.)
+       if (!last_phase) {
+               void *context = get_gl_context_identifier();
+               fbo = resource_pool->create_fbo(context, (*output_textures)[phase]);
+               glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+               glViewport(0, 0, phase->output_width, phase->output_height);
+       }
+       // 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(glsl_program_num, phase->effect_ids[node], &sampler_num);
+               check_error();
+               if (node->effect->is_single_texture()) {
+                       assert(sampler_num - old_sampler_num == 1);
+                       node->bound_sampler_num = old_sampler_num;
+               } else {
+                       node->bound_sampler_num = -1;
+               }
+       }
+       glBindVertexArray(phase->vao);
+       check_error();
+       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+       check_error();
+       for (unsigned i = 0; i < phase->effects.size(); ++i) {
+               Node *node = phase->effects[i];
+               node->effect->clear_gl_state();
+       }
+       if (!last_phase) {
+               resource_pool->release_fbo(fbo);
+       }
+ }
+ void EffectChain::setup_rtt_sampler(GLuint glsl_program_num, int sampler_num, const string &effect_id, bool use_mipmaps)
+ {
+       glActiveTexture(GL_TEXTURE0 + sampler_num);
+       check_error();
+       if (use_mipmaps) {
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+               check_error();
+       } else {
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+               check_error();
+       }
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+       check_error();
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+       check_error();
+       string texture_name = string("tex_") + effect_id;
+       glUniform1i(glGetUniformLocation(glsl_program_num, texture_name.c_str()), sampler_num);
+       check_error();
+ }
  }  // namespace movit
diff --combined effect_chain.h
index a1bf3cb80241167b6f0bda72bf1ea3e974ed98d3,903018bc3ab87a60dd159e3ff13d8edcec0b3171..e7d99d54821928c1248f6456c461ba1f63525eed
@@@ -17,7 -17,7 +17,7 @@@
  // the EffectChain holds textures and other OpenGL objects that are tied to the
  // context.
  
 -#include <GL/glew.h>
 +#include <epoxy/gl.h>
  #include <stdio.h>
  #include <map>
  #include <set>
@@@ -235,6 -235,13 +235,13 @@@ private
        // as the last effect. Also pushes all phases in order onto <phases>.
        Phase *construct_phase(Node *output, std::map<Node *, Phase *> *completed_effects);
  
+       // Execute one phase, ie. set up all inputs, effects and outputs, and render the quad.
+       void execute_phase(Phase *phase, bool last_phase, std::map<Phase *, GLuint> *output_textures, std::set<Phase *> *generated_mipmaps);
+       // Set up the given sampler number for sampling from an RTT texture,
+       // and bind it to "tex_" plus the given GLSL variable.
+       void setup_rtt_sampler(GLuint glsl_program_num, int sampler_num, const std::string &effect_id, bool use_mipmaps);
        // Output the current graph to the given file in a Graphviz-compatible format;
        // only useful for debugging.
        void output_dot(const char *filename);