Merge branch 'master' into epoxy
[movit] / slice_effect.cpp
1 #include <epoxy/gl.h>
2
3 #include "slice_effect.h"
4 #include "effect_util.h"
5 #include "util.h"
6
7 using namespace std;
8
9 namespace movit {
10
11 SliceEffect::SliceEffect()
12 {
13         register_int("input_slice_size", &input_slice_size);
14         register_int("output_slice_size", &output_slice_size);
15         register_int("direction", (int *)&direction);
16 }
17
18 string SliceEffect::output_fragment_shader()
19 {
20         char buf[256];
21         sprintf(buf, "#define DIRECTION_VERTICAL %d\n", (direction == VERTICAL));
22         return buf + read_file("slice_effect.frag");
23 }
24         
25 void SliceEffect::inform_input_size(unsigned input_num, unsigned width, unsigned height)
26 {
27         assert(input_num == 0);
28         input_width = width;
29         input_height = height;
30 }
31
32 void SliceEffect::get_output_size(unsigned *width, unsigned *height,
33                                   unsigned *virtual_width, unsigned *virtual_height) const
34 {
35         if (direction == HORIZONTAL) {
36                 *width = div_round_up(input_width, input_slice_size) * output_slice_size;
37                 *height = input_height; 
38         } else {
39                 *width = input_width;   
40                 *height = div_round_up(input_height, input_slice_size) * output_slice_size;
41         }
42         *virtual_width = *width;
43         *virtual_height = *height;
44 }
45
46 void SliceEffect::set_gl_state(GLuint glsl_program_num, const string &prefix, unsigned *sampler_num)
47 {
48         Effect::set_gl_state(glsl_program_num, prefix, sampler_num);
49
50         unsigned output_width, output_height;
51         get_output_size(&output_width, &output_height, &output_width, &output_height);
52
53         if (direction == HORIZONTAL) {
54                 set_uniform_float(glsl_program_num, prefix, "output_coord_to_slice_num", float(output_width) / float(output_slice_size));
55                 set_uniform_float(glsl_program_num, prefix, "slice_num_to_input_coord", float(input_slice_size) / float(input_width));
56                 set_uniform_float(glsl_program_num, prefix, "slice_offset_to_input_coord", float(output_slice_size) / float(input_width));
57         } else {
58                 set_uniform_float(glsl_program_num, prefix, "output_coord_to_slice_num", float(output_height) / float(output_slice_size));
59                 set_uniform_float(glsl_program_num, prefix, "slice_num_to_input_coord", float(input_slice_size) / float(input_height));
60                 set_uniform_float(glsl_program_num, prefix, "slice_offset_to_input_coord", float(output_slice_size) / float(input_height));
61         }
62
63         // Normalized coordinates could potentially cause blurring of the
64         // image; it's not critical, but we have set changes_output_size()
65         // and needs_texture_bounce(), so simply turning off the interpolation
66         // is allowed.
67         assert(*sampler_num == 1);
68         glActiveTexture(GL_TEXTURE0);
69         check_error();
70         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
71         check_error();
72         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
73         check_error();
74 }
75
76 }  // namespace movit