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 
7 
8 #include "../proc/synthetic-stream.h"
9 #include "synthetic-stream-gl.h"
10 #include "../proc/disparity-transform.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  auto size = static_cast<GLsizei>(curr_map.size());
155  glBindTexture(GL_TEXTURE_2D, _cm_texture);
156  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, size, 1, 0, GL_RGB, GL_FLOAT, curr_map.data());
159 
160  _enabled = glsl_enabled() ? 1 : 0;
161  }
162 
164  : librealsense::colorizer("Depth Visualization (GLSL)"), _cm_texture(0)
165  {
166  _fhist = std::vector<float>(MAX_DEPTH, 0);
167  _fhist_data = _fhist.data();
169 
170  auto opt = std::make_shared<librealsense::ptr_option<int>>(
171  0, 1, 0, 1, &_enabled, "GLSL enabled");
173 
174  initialize();
175  }
176 
178  {
179  perform_gl_action([&]()
180  {
182  }, []{});
183  }
184 
186  {
187  float total = float(hist[MAX_DEPTH-1]);
188  for (int i = 0; i < MAX_DEPTH; i++)
189  f[i] = hist[i] / total;
190  }
191 
193  {
194  if(f.as<rs2::depth_frame>())
195  _depth_units = ((depth_frame*)f.get())->get_units();
196  if (f.get_profile().get() != _source_stream_profile.get())
197  {
204  _width = vp.width(); _height = vp.height();
205 
207  _d2d_convert_factor = info.d2d_convert_factor;
208 
209  perform_gl_action([&]()
210  {
211  _fbo = std::make_shared<fbo>(_width, _height);
212  }, [this] {
213  _enabled = false;
214  });
215  }
216 
217  rs2::frame res = f;
218 
219  perform_gl_action([&]()
220  {
221  //scoped_timer t("colorizer.gl");
222  auto& curr_map = _maps[_map_index]->get_cache();
223 
225  {
227  auto size = static_cast<GLsizei>(curr_map.size());
228  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, size, 1, 0, GL_RGB, GL_FLOAT, curr_map.data());
231 
233  }
234 
236 
237  if (!res) return;
238 
239  auto fi = (frame_interface*)f.get();
240  auto df = dynamic_cast<librealsense::depth_frame*>(fi);
241  _depth_units = df->get_units();
242  bool disparity = f.get_profile().format() == RS2_FORMAT_DISPARITY32 ? true : false;
243 
244  auto gf = dynamic_cast<gpu_addon_interface*>((frame_interface*)res.get());
245 
246  uint32_t depth_texture;
247  uint32_t hist_texture = _cm_texture;
248 
249  if (auto input_frame = f.as<rs2::gl::gpu_frame>())
250  {
251  depth_texture = input_frame.get_texture_id(0);
252  hist_texture = input_frame.get_texture_id(1);
253  }
254  else
255  {
256  glGenTextures(1, &depth_texture);
257  glBindTexture(GL_TEXTURE_2D, depth_texture);
258 
259  if (disparity)
260  {
262  }
263  else
264  {
266  }
267 
270 
271  if (_equalize)
272  {
273  glGenTextures(1, &hist_texture);
274  glBindTexture(GL_TEXTURE_2D, hist_texture);
275 
276  if (disparity)
277  {
278  update_histogram(_hist_data, reinterpret_cast<const float*>(f.get_data()), _width, _height);
281  }
282  else
283  {
284  update_histogram(_hist_data, reinterpret_cast<const uint16_t*>(f.get_data()), _width, _height);
287  }
288 
291  }
292  }
293 
294  uint32_t output_rgb;
295  gf->get_gpu_section().output_texture(0, &output_rgb, TEXTYPE_RGB);
296  glBindTexture(GL_TEXTURE_2D, output_rgb);
300 
301  gf->get_gpu_section().set_size(_width, _height);
302 
305 
306  glBindTexture(GL_TEXTURE_2D, output_rgb);
307  _fbo->createTextureAttachment(output_rgb);
308 
309  _fbo->bind();
310  glClearColor(1, 0, 0, 1);
312 
313  auto& shader = (colorize_shader&)_viz->get_shader();
314  shader.begin();
315  float max = _max;;
316  float min = _min;;
317  if (disparity)
318  {
319  auto __min = _min;
320  if (__min < 1e-6f) { __min = 1e-6f; } // Min value set to prevent zero division. only when _min is zero.
321  max = (_d2d_convert_factor / (__min)) * _depth_units + .5f;
322  min = (_d2d_convert_factor / (_max)) * _depth_units + .5f;
323  }
324  shader.set_params(_depth_units, min, max, MAX_DISPARITY, _equalize, disparity);
325  shader.end();
326 
327  glActiveTexture(GL_TEXTURE0 + shader.histogram_slot());
328  glBindTexture(GL_TEXTURE_2D, hist_texture);
329 
330  glActiveTexture(GL_TEXTURE0 + shader.color_map_slot());
332 
333  glActiveTexture(GL_TEXTURE0 + shader.texture_slot());
334  glBindTexture(GL_TEXTURE_2D, depth_texture);
335 
336  _viz->draw_texture(depth_texture);
337 
338  glActiveTexture(GL_TEXTURE0 + shader.texture_slot());
339 
340  _fbo->unbind();
341 
343 
344  if (!f.is<rs2::gl::gpu_frame>())
345  {
346  if (_equalize)
347  {
348  glDeleteTextures(1, &hist_texture);
349  }
350  glDeleteTextures(1, &depth_texture);
351  }
352  },
353  [this]{
354  _enabled = false;
355  });
356 
357  return res;
358  }
359  }
360 }
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
static const int MAX_DEPTH
Definition: colorizer.h:117
void add_extension(rs2_extension ex)
Definition: source.h:45
#define GL_TEXTURE_2D
rs2_format format() const
Definition: rs_frame.hpp:44
#define GL_UNSIGNED_BYTE
uint32_t _is_disparity_location
uint32_t _min_depth_location
#define GL_RGB16F
int GLsizei
#define GL_R32F
Definition: animated.h:9
#define GL_LINEAR
int histogram_slot() const
bool is() const
Definition: rs_frame.hpp:572
#define glTexImage2D
e
Definition: rmse.py:177
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
void register_option(rs2_option id, std::shared_ptr< option > option)
Definition: options.h:86
#define glActiveTexture
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:327
#define GL_TEXTURE0
#define glGenTextures
#define GL_FLOAT
GLsizeiptr size
#define GL_COLOR_BUFFER_BIT
#define glBindFramebuffer
#define glTexParameteri
uint32_t _max_disparity_location
unsigned int uint32_t
Definition: stdint.h:80
#define glClear
int color_map_slot() const
static const int MAX_DISPARITY
Definition: colorizer.h:118
std::vector< color_map * > _maps
Definition: colorizer.h:159
#define GL_TEXTURE_MIN_FILTER
T as() const
Definition: rs_frame.hpp:582
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
const rs2_stream_profile * get() const
Definition: rs_frame.hpp:137
GLfloat units
float disparity
Definition: t265_stereo.py:241
const void * get_data() const
Definition: rs_frame.hpp:547
#define GL_RED
#define RS2_EXTENSION_VIDEO_FRAME_GL
int min(int a, int b)
Definition: lz4s.c:73
#define glBindTexture
GLdouble f
void perform_gl_action(T action, S fallback)
static const char * fragment_shader_text
#define glClearColor
int texture_slot() const
#define GL_COLOR_ATTACHMENT0
int i
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)
rs2_frame * get() const
Definition: rs_frame.hpp:592
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
stream_profile get_profile() const
Definition: rs_frame.hpp:559


librealsense2
Author(s): LibRealSense ROS Team
autogenerated on Thu Dec 22 2022 03:43:16