colorizer-gl.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2019 Intel Corporation. All Rights Reserved.
3 
4 #include "../include/librealsense2/hpp/rs_sensor.hpp"
5 #include "../include/librealsense2/hpp/rs_processing.hpp"
6 #include "../include/librealsense2-gl/rs_processing_gl.hpp"
7 
9 #include "synthetic-stream-gl.h"
11 #include "colorizer-gl.h"
12 #include "option.h"
13 
14 #ifndef NOMINMAX
15 #define NOMINMAX
16 #endif // NOMINMAX
17 
18 #include <glad/glad.h>
19 
20 #include <iostream>
21 #include <chrono>
22 #include <strstream>
23 
24 static const char* fragment_shader_text =
25 "#version 110\n"
26 "varying vec2 textCoords;\n"
27 "uniform sampler2D textureSampler;\n"
28 "uniform sampler2D cmSampler;\n"
29 "uniform sampler2D histSampler;\n"
30 "uniform float opacity;\n"
31 "uniform float depth_units;\n"
32 "uniform float min_depth;\n"
33 "uniform float max_depth;\n"
34 "uniform float max_disparity;\n"
35 "uniform float equalize;\n"
36 "uniform float disparity;\n"
37 "void main(void) {\n"
38 " vec2 tex = vec2(textCoords.x, 1.0 - textCoords.y);\n"
39 " vec4 depth = texture2D(textureSampler, tex);\n"
40 " float dx = depth.x;\n"
41 " float dy = depth.y;\n"
42 " float nd = dx + dy * 256.0;\n"
43 " float d = 0.0;\n"
44 " if (disparity > 0.0) {;\n"
45 " d = dx;\n"
46 " } else {\n"
47 " d = nd * 256.0;\n"
48 " }\n"
49 " if (d > 0.0){\n"
50 " float f = 0.0;\n"
51 " if (equalize > 0.0){\n"
52 " float x;\n"
53 " float y;\n"
54 " vec4 hist;\n"
55 " if (disparity > 0.0) {;\n"
56 " hist = texture2D(histSampler, vec2(d / max_disparity, 0.0));\n"
57 " } else {\n"
58 " x = dx * 0.99;\n"
59 " y = dy + (1.0 / 256.0);\n"
60 " hist = texture2D(histSampler, vec2(x, y));\n"
61 " }\n"
62 " f = hist.x;\n"
63 " } else {\n"
64 " if (disparity > 0.0) {\n"
65 " f = ((d - min_depth) / (max_depth - min_depth));\n"
66 " } else {\n"
67 " f = (d * depth_units - min_depth) / (max_depth - min_depth);\n"
68 " }\n"
69 " }\n"
70 " f = clamp(f, 0.0, 0.99);\n"
71 " vec4 color = texture2D(cmSampler, vec2(f, 0.0));\n"
72 " gl_FragColor = vec4(color.x / 256.0, color.y / 256.0, color.z / 256.0, opacity);\n"
73 " } else {\n"
74 " gl_FragColor = vec4(0.0, 0.0, 0.0, opacity);\n"
75 " }\n"
76 "}";
77 
78 using namespace rs2;
79 using namespace librealsense::gl;
80 
82 {
83 public:
86  texture_2d_shader::default_vertex_shader(),
87  fragment_shader_text, "position", "textureCoords"))
88  {
89  _depth_units_location = _shader->get_uniform_location("depth_units");
90  _min_depth_location = _shader->get_uniform_location("min_depth");
91  _max_depth_location = _shader->get_uniform_location("max_depth");
92  _max_disparity_location = _shader->get_uniform_location("max_disparity");
93  _equalize_location = _shader->get_uniform_location("equalize");
94  _is_disparity_location = _shader->get_uniform_location("disparity");
95 
96  auto texture0_sampler_location = _shader->get_uniform_location("textureSampler");
97  auto texture1_sampler_location = _shader->get_uniform_location("cmSampler");
98  auto texture2_sampler_location = _shader->get_uniform_location("histSampler");
99 
100  _shader->begin();
101  _shader->load_uniform(texture0_sampler_location, texture_slot());
102  _shader->load_uniform(texture1_sampler_location, color_map_slot());
103  _shader->load_uniform(texture2_sampler_location, histogram_slot());
104  _shader->end();
105  }
106 
107  int texture_slot() const { return 0; }
108  int color_map_slot() const { return 1; }
109  int histogram_slot() const { return 2; }
110 
111  void set_params(float units, float min, float max, float max_disparity, bool equalize, bool disparity)
112  {
113  _shader->load_uniform(_depth_units_location, units);
114  _shader->load_uniform(_min_depth_location, min);
115  _shader->load_uniform(_max_depth_location, max);
116  _shader->load_uniform(_max_disparity_location, max_disparity);
117  _shader->load_uniform(_equalize_location, equalize ? 1.f : 0.f);
118  _shader->load_uniform(_is_disparity_location, disparity ? 1.f : 0.f);
119  }
120 
121 private:
128 };
129 
130 using namespace rs2;
131 
132 namespace librealsense
133 {
134  namespace gl
135  {
136  void colorizer::cleanup_gpu_resources()
137  {
138  _viz.reset();
139  _fbo.reset();
140 
141  if (_cm_texture) glDeleteTextures(1, &_cm_texture);
142 
143  _enabled = 0;
144  }
145 
146  void colorizer::create_gpu_resources()
147  {
148  _viz = std::make_shared<visualizer_2d>(std::make_shared<colorize_shader>());
149  _fbo = std::make_shared<fbo>(_width, _height);
150 
151  glGenTextures(1, &_cm_texture);
152  auto& curr_map = _maps[_map_index]->get_cache();
153  _last_selected_cm = _map_index;
154  glBindTexture(GL_TEXTURE_2D, _cm_texture);
155  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, curr_map.size(), 1, 0, GL_RGB, GL_FLOAT, curr_map.data());
158 
159  _enabled = glsl_enabled() ? 1 : 0;
160  }
161 
163  : librealsense::colorizer("Depth Visualization (GLSL)"), _cm_texture(0)
164  {
165  _fhist = std::vector<float>(MAX_DEPTH, 0);
166  _fhist_data = _fhist.data();
168 
169  auto opt = std::make_shared<librealsense::ptr_option<int>>(
170  0, 1, 0, 1, &_enabled, "GLSL enabled");
172 
173  initialize();
174  }
175 
177  {
178  perform_gl_action([&]()
179  {
181  }, []{});
182  }
183 
185  {
186  float total = float(hist[MAX_DEPTH-1]);
187  for (int i = 0; i < MAX_DEPTH; i++)
188  f[i] = hist[i] / total;
189  }
190 
192  {
193  if (f.get_profile().get() != _source_stream_profile.get())
194  {
201  _width = vp.width(); _height = vp.height();
202 
204  _depth_units = info.depth_units;
205  _d2d_convert_factor = info.d2d_convert_factor;
206 
207  perform_gl_action([&]()
208  {
209  _fbo = std::make_shared<fbo>(_width, _height);
210  }, [this] {
211  _enabled = false;
212  });
213  }
214 
215  rs2::frame res = f;
216 
217  perform_gl_action([&]()
218  {
219  //scoped_timer t("colorizer.gl");
220  auto& curr_map = _maps[_map_index]->get_cache();
221 
223  {
225  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, curr_map.size(), 1, 0, GL_RGB, GL_FLOAT, curr_map.data());
228 
230  }
231 
233 
234  if (!res) return;
235 
236  auto fi = (frame_interface*)f.get();
237  auto df = dynamic_cast<librealsense::depth_frame*>(fi);
238  auto depth_units = df->get_units();
239  bool disparity = f.get_profile().format() == RS2_FORMAT_DISPARITY32 ? true : false;
240 
241  auto gf = dynamic_cast<gpu_addon_interface*>((frame_interface*)res.get());
242 
243  uint32_t depth_texture;
244  uint32_t hist_texture = _cm_texture;
245 
246  if (auto input_frame = f.as<rs2::gl::gpu_frame>())
247  {
248  depth_texture = input_frame.get_texture_id(0);
249  hist_texture = input_frame.get_texture_id(1);
250  }
251  else
252  {
253  glGenTextures(1, &depth_texture);
254  glBindTexture(GL_TEXTURE_2D, depth_texture);
255 
256  if (disparity)
257  {
259  }
260  else
261  {
263  }
264 
267 
268  if (_equalize)
269  {
270  glGenTextures(1, &hist_texture);
271  glBindTexture(GL_TEXTURE_2D, hist_texture);
272 
273  if (disparity)
274  {
275  update_histogram(_hist_data, reinterpret_cast<const float*>(f.get_data()), _width, _height);
278  }
279  else
280  {
281  update_histogram(_hist_data, reinterpret_cast<const uint16_t*>(f.get_data()), _width, _height);
284  }
285 
288  }
289  }
290 
291  uint32_t output_rgb;
292  gf->get_gpu_section().output_texture(0, &output_rgb, TEXTYPE_RGB);
293  glBindTexture(GL_TEXTURE_2D, output_rgb);
297 
298  gf->get_gpu_section().set_size(_width, _height);
299 
302 
303  glBindTexture(GL_TEXTURE_2D, output_rgb);
304  _fbo->createTextureAttachment(output_rgb);
305 
306  _fbo->bind();
307  glClearColor(1, 0, 0, 1);
309 
310  auto& shader = (colorize_shader&)_viz->get_shader();
311  shader.begin();
312  float max = _max;;
313  float min = _min;;
314  if (disparity)
315  {
316  auto __min = _min;
317  if (__min < 1e-6f) { __min = 1e-6f; } // Min value set to prevent zero division. only when _min is zero.
318  max = (_d2d_convert_factor / (__min)) * _depth_units + .5f;
319  min = (_d2d_convert_factor / (_max)) * depth_units + .5f;
320  }
321  shader.set_params(depth_units, min, max, MAX_DISPARITY, _equalize, disparity);
322  shader.end();
323 
324  glActiveTexture(GL_TEXTURE0 + shader.histogram_slot());
325  glBindTexture(GL_TEXTURE_2D, hist_texture);
326 
327  glActiveTexture(GL_TEXTURE0 + shader.color_map_slot());
329 
330  glActiveTexture(GL_TEXTURE0 + shader.texture_slot());
331  glBindTexture(GL_TEXTURE_2D, depth_texture);
332 
333  _viz->draw_texture(depth_texture);
334 
335  glActiveTexture(GL_TEXTURE0 + shader.texture_slot());
336 
337  _fbo->unbind();
338 
340 
341  if (!f.is<rs2::gl::gpu_frame>())
342  {
343  if (_equalize)
344  {
345  glDeleteTextures(1, &hist_texture);
346  }
347  glDeleteTextures(1, &depth_texture);
348  }
349  },
350  [this]{
351  _enabled = false;
352  });
353 
354  return res;
355  }
356  }
357 }
void cleanup_gpu_resources() override
#define GL_TEXTURE_MAG_FILTER
rs2::frame process_frame(const rs2::frame_source &source, const rs2::frame &f) override
uint32_t _depth_units_location
#define GL_RG8
rs2::stream_profile _source_stream_profile
Definition: colorizer.h:167
rs2_frame * get() const
Definition: rs_frame.hpp:590
static const int MAX_DEPTH
Definition: colorizer.h:117
void add_extension(rs2_extension ex)
Definition: source.h:45
#define GL_TEXTURE_2D
int color_map_slot() const
#define GL_UNSIGNED_BYTE
uint32_t _is_disparity_location
stream_profile get_profile() const
Definition: rs_frame.hpp:557
uint32_t _min_depth_location
#define GL_RGB16F
#define GL_R32F
const void * get_data() const
Definition: rs_frame.hpp:545
Definition: cah-model.h:10
int texture_slot() const
#define GL_LINEAR
int histogram_slot() const
GLenum src
Definition: glext.h:1751
#define glTexImage2D
e
Definition: rmse.py:177
void register_option(rs2_option id, std::shared_ptr< option > option)
Definition: options.h:86
#define glActiveTexture
frame allocate_video_frame(const stream_profile &profile, const frame &original, int new_bpp=0, int new_width=0, int new_height=0, int new_stride=0, rs2_extension frame_type=RS2_EXTENSION_VIDEO_FRAME) const
std::shared_ptr< rs2::visualizer_2d > _viz
Definition: colorizer-gl.h:53
static info update_info_from_frame(const rs2::frame &f)
def info(name, value, persistent=False)
Definition: test.py:301
GLdouble f
#define GL_TEXTURE0
bool is() const
Definition: rs_frame.hpp:570
#define glGenTextures
#define GL_FLOAT
#define GL_COLOR_BUFFER_BIT
#define glBindFramebuffer
#define glTexParameteri
uint32_t _max_disparity_location
unsigned int uint32_t
Definition: stdint.h:80
#define glClear
static const int MAX_DISPARITY
Definition: colorizer.h:118
std::vector< color_map * > _maps
Definition: colorizer.h:159
#define GL_TEXTURE_MIN_FILTER
rs2::stream_profile _target_stream_profile
Definition: colorizer.h:166
int stream_index() const
Definition: rs_frame.hpp:34
#define GL_RG
std::vector< float > _fhist
Definition: colorizer-gl.h:50
#define glDeleteTextures
GLfloat units
float disparity
Definition: t265_stereo.py:241
rs2_format format() const
Definition: rs_frame.hpp:44
#define GL_RED
#define RS2_EXTENSION_VIDEO_FRAME_GL
int min(int a, int b)
Definition: lz4s.c:73
const rs2_stream_profile * get() const
Definition: rs_frame.hpp:137
#define glBindTexture
void perform_gl_action(T action, S fallback)
static const char * fragment_shader_text
#define glClearColor
#define GL_COLOR_ATTACHMENT0
int i
GLuint res
Definition: glext.h:8856
static void update_histogram(int *hist, const T *depth_data, int w, int h)
Definition: colorizer.h:104
#define GL_RGB
#define glDrawBuffer
#define GL_NEAREST
rs2_stream stream_type() const
Definition: rs_frame.hpp:39
uint32_t _equalize_location
std::shared_ptr< rs2::fbo > _fbo
Definition: colorizer-gl.h:54
static void populate_floating_histogram(float *f, int *hist)
void set_params(float units, float min, float max, float max_disparity, bool equalize, bool disparity)
stream_profile clone(rs2_stream type, int index, rs2_format format) const
Definition: rs_frame.hpp:63
#define GL_FRAMEBUFFER
uint32_t _max_depth_location
T as() const
Definition: rs_frame.hpp:580


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:11