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