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