1 #include <pcl/simulation/sum_reduce.h>
2
3 using namespace pcl::simulation;
4
SumReduce(int width,int height,int levels)5 pcl::simulation::SumReduce::SumReduce(int width, int height, int levels)
6 : levels_(levels), width_(width), height_(height)
7 {
8 std::cout << "SumReduce: levels: " << levels_ << std::endl;
9
10 // Load shader
11 sum_program_ = gllib::Program::Ptr(new gllib::Program());
12 // TODO: to remove file dependency include the shader source in the binary
13 if (!sum_program_->addShaderFile("sum_score.vert", gllib::VERTEX)) {
14 std::cout << "Failed loading vertex shader" << std::endl;
15 exit(-1);
16 }
17
18 // TODO: to remove file dependency include the shader source in the binary
19 if (!sum_program_->addShaderFile("sum_score.frag", gllib::FRAGMENT)) {
20 std::cout << "Failed loading fragment shader" << std::endl;
21 exit(-1);
22 }
23
24 sum_program_->link();
25
26 // Setup the framebuffer object for rendering
27 glGenFramebuffers(1, &fbo_);
28 arrays_ = new GLuint[levels_];
29
30 glGenTextures(levels_, arrays_);
31
32 int level_width = width_;
33 int level_height = height_;
34
35 for (int i = 0; i < levels_; ++i) {
36 level_width /= 2;
37 level_height /= 2;
38
39 glBindTexture(GL_TEXTURE_2D, arrays_[i]);
40 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
41 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
42 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
43 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
44 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
45 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
46 glTexImage2D(GL_TEXTURE_2D,
47 0,
48 GL_R32F,
49 level_width,
50 level_height,
51 0,
52 GL_RED,
53 GL_FLOAT,
54 nullptr);
55 glBindTexture(GL_TEXTURE_2D, 0);
56 }
57 }
58
~SumReduce()59 pcl::simulation::SumReduce::~SumReduce()
60 {
61 glDeleteTextures(levels_, arrays_);
62 glDeleteFramebuffers(1, &fbo_);
63 }
64
65 void
sum(GLuint input_array,float * output_array)66 pcl::simulation::SumReduce::sum(GLuint input_array, float* output_array)
67 {
68 if (gllib::getGLError() != GL_NO_ERROR) {
69 std::cout << "SumReduce::sum enter" << std::endl;
70 }
71
72 glDisable(GL_DEPTH_TEST);
73
74 glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
75 int width = width_;
76 int height = height_;
77
78 glActiveTexture(GL_TEXTURE0);
79 glBindTexture(GL_TEXTURE_2D, input_array);
80
81 // use program
82 sum_program_->use();
83 glUniform1i(sum_program_->getUniformLocation("ArraySampler"), 0);
84
85 if (gllib::getGLError() != GL_NO_ERROR) {
86 std::cout << "SumReduce::sum set sampler" << std::endl;
87 }
88
89 for (int i = 0; i < levels_; ++i) {
90 glFramebufferTexture2D(
91 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, arrays_[i], 0);
92 glDrawBuffer(GL_COLOR_ATTACHMENT0);
93
94 glViewport(0, 0, width / 2, height / 2);
95
96 float step_x = 1.0f / float(width);
97 float step_y = 1.0f / float(height);
98 sum_program_->setUniform("step_x", step_x);
99 sum_program_->setUniform("step_y", step_y);
100 // float step_x = 1.0f / static_cast<float> (width);
101 // float step_y = 1.0f / static_cast<float> (height);
102
103 quad_.render();
104
105 if (gllib::getGLError() != GL_NO_ERROR) {
106 std::cout << "SumReduce::sum render" << std::endl;
107 }
108
109 width /= 2;
110 height /= 2;
111
112 glActiveTexture(GL_TEXTURE0);
113 glBindTexture(GL_TEXTURE_2D, arrays_[i]);
114 }
115
116 glBindFramebuffer(GL_FRAMEBUFFER, 0);
117
118 glActiveTexture(GL_TEXTURE0);
119 glBindTexture(GL_TEXTURE_2D, 0);
120
121 glUseProgram(0);
122
123 // Final results is in arrays_[levels_-1]
124 glActiveTexture(GL_TEXTURE0);
125 glBindTexture(GL_TEXTURE_2D, arrays_[levels_ - 1]);
126 glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_FLOAT, output_array);
127 glBindTexture(GL_TEXTURE_2D, 0);
128
129 if (gllib::getGLError() != GL_NO_ERROR) {
130 std::cout << "Error: SumReduce exit" << std::endl;
131 }
132 }
133