]> git.sesse.net Git - movit/blob - slice_effect.cpp
Add a notice to render_to_screen() that it might be suboptimal.
[movit] / slice_effect.cpp
1 #include <epoxy/gl.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         : input_slice_size(1),
14           output_slice_size(1),
15           offset(0),
16           direction(VERTICAL)
17 {
18         register_int("input_slice_size", &input_slice_size);
19         register_int("output_slice_size", &output_slice_size);
20         register_int("offset", &offset);
21         register_int("direction", (int *)&direction);
22         register_uniform_float("output_coord_to_slice_num", &uniform_output_coord_to_slice_num);
23         register_uniform_float("slice_num_to_input_coord", &uniform_slice_num_to_input_coord);
24         register_uniform_float("slice_offset_to_input_coord", &uniform_slice_offset_to_input_coord);
25         register_uniform_float("normalized_offset", &uniform_offset);
26 }
27
28 string SliceEffect::output_fragment_shader()
29 {
30         char buf[256];
31         sprintf(buf, "#define DIRECTION_VERTICAL %d\n", (direction == VERTICAL));
32         return buf + read_file("slice_effect.frag");
33 }
34         
35 void SliceEffect::inform_input_size(unsigned input_num, unsigned width, unsigned height)
36 {
37         assert(input_num == 0);
38         input_width = width;
39         input_height = height;
40 }
41
42 void SliceEffect::get_output_size(unsigned *width, unsigned *height,
43                                   unsigned *virtual_width, unsigned *virtual_height) const
44 {
45         if (direction == HORIZONTAL) {
46                 *width = div_round_up(input_width, input_slice_size) * output_slice_size;
47                 *height = input_height; 
48         } else {
49                 *width = input_width;   
50                 *height = div_round_up(input_height, input_slice_size) * output_slice_size;
51         }
52         *virtual_width = *width;
53         *virtual_height = *height;
54 }
55
56 void SliceEffect::set_gl_state(GLuint glsl_program_num, const string &prefix, unsigned *sampler_num)
57 {
58         Effect::set_gl_state(glsl_program_num, prefix, sampler_num);
59
60         unsigned output_width, output_height;
61         get_output_size(&output_width, &output_height, &output_width, &output_height);
62
63         if (direction == HORIZONTAL) {
64                 uniform_output_coord_to_slice_num = float(output_width) / float(output_slice_size);
65                 uniform_slice_num_to_input_coord = float(input_slice_size) / float(input_width);
66                 uniform_slice_offset_to_input_coord = float(output_slice_size) / float(input_width);
67                 uniform_offset = float(offset) / float(input_width);
68         } else {
69                 uniform_output_coord_to_slice_num = float(output_height) / float(output_slice_size);
70                 uniform_slice_num_to_input_coord = float(input_slice_size) / float(input_height);
71                 uniform_slice_offset_to_input_coord = float(output_slice_size) / float(input_height);
72                 uniform_offset = float(offset) / float(input_height);
73         }
74
75         // Normalized coordinates could potentially cause blurring of the image.
76         // It isn't critical, but still good practice.
77         Node *self = chain->find_node_for_effect(this);
78         glActiveTexture(chain->get_input_sampler(self, 0));
79         check_error();
80         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
81         check_error();
82         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
83         check_error();
84 }
85
86 }  // namespace movit