example.hpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2015 Intel Corporation. All Rights Reserved.
3 
4 #define GLFW_INCLUDE_GLU
5 #include <GLFW/glfw3.h>
6 
7 #include <sstream>
8 #include <vector>
9 
10 inline void make_depth_histogram(uint8_t rgb_image[640*480*3], const uint16_t depth_image[], int width, int height)
11 {
12  static uint32_t histogram[0x10000];
13  memset(histogram, 0, sizeof(histogram));
14 
15  for(int i = 0; i < width*height; ++i) ++histogram[depth_image[i]];
16  for(int i = 2; i < 0x10000; ++i) histogram[i] += histogram[i-1]; // Build a cumulative histogram for the indices in [1,0xFFFF]
17  for(int i = 0; i < width*height; ++i)
18  {
19  if(uint16_t d = depth_image[i])
20  {
21  int f = histogram[d] * 255 / histogram[0xFFFF]; // 0-255 based on histogram location
22  rgb_image[i*3 + 0] = 255 - f;
23  rgb_image[i*3 + 1] = 0;
24  rgb_image[i*3 + 2] = f;
25  }
26  else
27  {
28  rgb_image[i*3 + 0] = 20;
29  rgb_image[i*3 + 1] = 5;
30  rgb_image[i*3 + 2] = 0;
31  }
32  }
33 }
34 
36 // Simple font loading code //
38 
40 
41 inline int get_text_width(const char * text)
42 {
43  return stb_easy_font_width((char *)text);
44 }
45 
46 inline void draw_text(int x, int y, const char * text)
47 {
48  char buffer[60000]; // ~300 chars
49  glEnableClientState(GL_VERTEX_ARRAY);
50  glVertexPointer(2, GL_FLOAT, 16, buffer);
51  glDrawArrays(GL_QUADS, 0, 4*stb_easy_font_print((float)x, (float)(y-7), (char *)text, nullptr, buffer, sizeof(buffer)));
52  glDisableClientState(GL_VERTEX_ARRAY);
53 }
54 
56 // Image display code //
58 
60 {
63  std::vector<uint8_t> rgb;
64 
66  double next_time;
67 
68 public:
69  texture_buffer() : texture(), last_timestamp(-1), fps(), num_frames(), next_time(1000) {}
70 
71  GLuint get_gl_handle() const { return texture; }
72 
73  void upload(const void * data, int width, int height, rs::format format, int stride = 0)
74  {
75  // If the frame timestamp has changed since the last time show(...) was called, re-upload the texture
76  if(!texture) glGenTextures(1, &texture);
77  glBindTexture(GL_TEXTURE_2D, texture);
78  stride = stride == 0 ? width : stride;
79  glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
80  switch(format)
81  {
82  case rs::format::any:
83  throw std::runtime_error("not a valid format");
84  case rs::format::z16:
86  rgb.resize(stride * height * 3);
87  make_depth_histogram(rgb.data(), reinterpret_cast<const uint16_t *>(data), stride, height);
88  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, stride, height, 0, GL_RGB, GL_UNSIGNED_BYTE, rgb.data());
89 
90  break;
91  case rs::format::xyz32f:
92  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT, data);
93  break;
94  case rs::format::yuyv: // Display YUYV by showing the luminance channel and packing chrominance into ignored alpha channel
95  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data);
96  break;
97  case rs::format::rgb8: case rs::format::bgr8: // Display both RGB and BGR by interpreting them RGB, to show the flipped byte ordering. Obviously, GL_BGR could be used on OpenGL 1.2+
98  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
99  break;
100  case rs::format::rgba8: case rs::format::bgra8: // Display both RGBA and BGRA by interpreting them RGBA, to show the flipped byte ordering. Obviously, GL_BGRA could be used on OpenGL 1.2+
101  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
102  break;
103  case rs::format::y8:
104  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
105  break;
106  case rs::format::y16:
107  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_SHORT, data);
108  break;
109  case rs::format::raw8:
110  glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
111  break;
112  case rs::format::raw10:
113  {
114  // Visualize Raw10 by performing a naive downsample. Each 2x2 block contains one red pixel, two green pixels, and one blue pixel, so combine them into a single RGB triple.
115  rgb.clear(); rgb.resize(width/2 * height/2 * 3);
116  auto out = rgb.data(); auto in0 = reinterpret_cast<const uint8_t *>(data), in1 = in0 + width*5/4;
117  for(int y=0; y<height; y+=2)
118  {
119  for(int x=0; x<width; x+=4)
120  {
121  *out++ = in0[0]; *out++ = (in0[1] + in1[0]) / 2; *out++ = in1[1]; // RGRG -> RGB RGB
122  *out++ = in0[2]; *out++ = (in0[3] + in1[2]) / 2; *out++ = in1[3]; // GBGB
123  in0 += 5; in1 += 5;
124  }
125  in0 = in1; in1 += width*5/4;
126  }
127  glPixelStorei(GL_UNPACK_ROW_LENGTH, width / 2); // Update row stride to reflect post-downsampling dimensions of the target texture
128  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width/2, height/2, 0, GL_RGB, GL_UNSIGNED_BYTE, rgb.data());
129  }
130  break;
131  case rs::format::raw16:
132  // All RAW formats will be treated and displayed as Greyscale images
133  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_SHORT, data);
134  break;
135  default:
136  {
137  std::stringstream ss;
138  ss << rs_format_to_string((rs_format)format) << " pixel format is not supported by the demo";
139  throw std::runtime_error(ss.str().c_str());
140  }
141  }
142  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
143  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
144  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
145  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
146  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
147  glBindTexture(GL_TEXTURE_2D, 0);
148  }
149 
151  {
152  if (stream <= rs::stream::fisheye)
153  assert(dev.is_stream_enabled(stream));
154 
155  const double timestamp = dev.get_frame_timestamp(stream);
156  if(timestamp != last_timestamp)
157  {
158  upload(dev.get_frame_data(stream), dev.get_stream_width(stream), dev.get_stream_height(stream), dev.get_stream_format(stream));
159  last_timestamp = timestamp;
160 
161  ++num_frames;
162  if(timestamp >= next_time)
163  {
164  fps = num_frames;
165  num_frames = 0;
166  next_time += 1000;
167  }
168  }
169  }
170 
171  void upload(rs::frame& frame)
172  {
173  const double timestamp = frame.get_timestamp();
174  if(timestamp != last_timestamp)
175  {
176  upload(frame.get_data(), frame.get_width(), frame.get_height(), frame.get_format(), (frame.get_stride() * 8) / frame.get_bpp());
177  last_timestamp = timestamp;
178 
179  ++num_frames;
180  if(timestamp >= next_time)
181  {
182  fps = num_frames;
183  num_frames = 0;
184  next_time += 1000;
185  }
186  }
187  }
188 
189  void show(float rx, float ry, float rw, float rh) const
190  {
191  glBindTexture(GL_TEXTURE_2D, texture);
192  glEnable(GL_TEXTURE_2D);
193  glBegin(GL_QUADS);
194  glTexCoord2f(0, 0); glVertex2f(rx, ry );
195  glTexCoord2f(1, 0); glVertex2f(rx+rw, ry );
196  glTexCoord2f(1, 1); glVertex2f(rx+rw, ry+rh);
197  glTexCoord2f(0, 1); glVertex2f(rx, ry+rh);
198  glEnd();
199  glDisable(GL_TEXTURE_2D);
200  glBindTexture(GL_TEXTURE_2D, 0);
201  }
202 
203  void print(int x, int y, const char * text)
204  {
205  char buffer[20000]; // ~100 chars
206 
207  glEnableClientState(GL_VERTEX_ARRAY);
208  glVertexPointer(2, GL_FLOAT, 16, buffer);
209  glDrawArrays(GL_QUADS, 0, 4*stb_easy_font_print((float)x, (float)y, (char *)text, nullptr, buffer, sizeof(buffer)));
210  glDisableClientState(GL_VERTEX_ARRAY);
211  }
212 
213  void show(rs::device & dev, rs::stream stream, int rx, int ry, int rw, int rh)
214  {
215  if((stream <= rs::stream::fisheye) && (!dev.is_stream_enabled(stream))) return;
216 
217  upload(dev, stream);
218 
219  int width = dev.get_stream_width(stream), height = dev.get_stream_height(stream);
220  float h = (float)rh, w = (float)rh * width / height;
221  if(w > rw)
222  {
223  float scale = rw/w;
224  w *= scale;
225  h *= scale;
226  }
227 
228  show(rx + (rw - w)/2, ry + (rh - h)/2, w, h);
229  std::ostringstream ss; ss << stream << ": " << width << " x " << height << " " << dev.get_stream_format(stream) << " (" << fps << "/" << dev.get_stream_framerate(stream) << ")" << ", F#: " << dev.get_frame_number(stream);
230  glColor3f(0,0,0);
231  draw_text(rx+9, ry+17, ss.str().c_str());
232  glColor3f(1,1,1);
233  draw_text(rx+8, ry+16, ss.str().c_str());
234  }
235 
236  void show(rs::stream stream, rs::format format, int stream_framerate, unsigned long long frame_number, double timestamp, int rx, int ry, int rw, int rh, int width, int height)
237  {
238  show(rx, ry, rw, rh, width, height);
239 
240  std::ostringstream ss; ss << stream << ": " << width << " x " << height << " " << format << " (" << fps << "/" << stream_framerate << ")" << ", F#: " << frame_number << ", TS: " << timestamp;
241  glColor3f(0,0,0);
242  draw_text(rx+9, ry+17, ss.str().c_str());
243  glColor3f(1,1,1);
244  draw_text(rx+8, ry+16, ss.str().c_str());
245  }
246 
247  void show(int rx, int ry, int rw, int rh, int width, int height)
248  {
249  float h = (float)rh, w = (float)rh * width / height;
250  if (w > rw)
251  {
252  float scale = rw / w;
253  w *= scale;
254  h *= scale;
255  }
256 
257  show(rx + (rw - w) / 2, ry + (rh - h) / 2, w, h);
258  }
259 
260  void show(const void * data, int width, int height, rs::format format, const std::string & caption, int rx, int ry, int rw, int rh)
261  {
262  if(!data) return;
263 
264  upload(data, width, height, format);
265 
266  float h = (float)rh, w = (float)rh * width / height;
267  if(w > rw)
268  {
269  float scale = rw/w;
270  w *= scale;
271  h *= scale;
272  }
273 
274  show(rx + (rw - w)/2, ry + (rh - h)/2, w, h);
275 
276  std::ostringstream ss; ss << caption << ": " << width << " x " << height << " " << format;
277  glColor3f(0,0,0);
278  draw_text(rx+9, ry+17, ss.str().c_str());
279  glColor3f(1,1,1);
280  draw_text(rx+8, ry+16, ss.str().c_str());
281  }
282 };
283 
284 inline void draw_depth_histogram(const uint16_t depth_image[], int width, int height)
285 {
286  static uint8_t rgb_image[640*480*3];
287  make_depth_histogram(rgb_image, depth_image, width, height);
288  glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, rgb_image);
289 }
Provides convenience methods relating to devices.
Definition: rs.hpp:567
int get_width() const
Returns image width in pixels.
Definition: rs.hpp:487
int get_stride() const
Retrieves frame stride, meaning the actual line width in memory in bytes (not the logical image width...
Definition: rs.hpp:514
void show(rs::stream stream, rs::format format, int stream_framerate, unsigned long long frame_number, double timestamp, int rx, int ry, int rw, int rh, int width, int height)
Definition: example.hpp:236
GLint GLint GLsizei GLsizei height
Definition: glext.h:112
void show(int rx, int ry, int rw, int rh, int width, int height)
Definition: example.hpp:247
void draw_depth_histogram(const uint16_t depth_image[], int width, int height)
Definition: example.hpp:284
GLint GLint GLint GLint GLint GLint y
Definition: glext.h:114
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9820
GLsizei stride
Definition: glext.h:378
static int stb_easy_font_print(float x, float y, char *text, unsigned char color[4], void *vertex_buffer, int vbuf_size)
GLsizei const GLchar *const * string
Definition: glext.h:683
int get_stream_width(stream stream) const
Retrieves width, in pixels, of a specific stream, equivalent to the width field from the stream&#39;s int...
Definition: rs.hpp:744
GLuint GLuint stream
Definition: glext.h:1774
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:1944
const void * get_frame_data(stream stream) const
Retrieves contents of latest frame on a stream.
Definition: rs.hpp:1050
format get_stream_format(stream stream) const
Retrieves pixel format for specific stream.
Definition: rs.hpp:766
GLuint buffer
Definition: glext.h:528
std::vector< uint8_t > rgb
Definition: example.hpp:63
double last_timestamp
Definition: example.hpp:62
void show(rs::device &dev, rs::stream stream, int rx, int ry, int rw, int rh)
Definition: example.hpp:213
void show(float rx, float ry, float rw, float rh) const
Definition: example.hpp:189
int get_height() const
Returns image height in pixels.
Definition: rs.hpp:496
stream
Streams are different types of data provided by RealSense devices.
Definition: rs.hpp:24
int get_stream_height(stream stream) const
Retrieves height, in pixels, of a specific stream, equivalent to the height field from the stream&#39;s i...
Definition: rs.hpp:755
bool is_stream_enabled(stream stream) const
Determines if specific stream is enabled.
Definition: rs.hpp:733
GLfloat f
Definition: glext.h:1868
format get_format() const
Retrieves frame format.
Definition: rs.hpp:534
format
Formats: defines how each stream can be encoded. rs_format specifies how a frame is represented in me...
Definition: rs.hpp:42
void print(int x, int y, const char *text)
Definition: example.hpp:203
int get_stream_framerate(stream stream) const
Retrieves frame rate for specific stream.
Definition: rs.hpp:777
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * data
Definition: glext.h:223
const void * get_data() const
Definition: rs.hpp:478
GLuint texture
Definition: example.hpp:61
unsigned long long get_frame_number(stream stream) const
Retrieves frame number.
Definition: rs.hpp:1039
rs_format
Formats: defines how each stream can be encoded.
Definition: rs.h:53
int get_text_width(const char *text)
Definition: example.hpp:41
double get_frame_timestamp(stream stream) const
Retrieves time at which the latest frame on a stream was captured.
Definition: rs.hpp:1028
void upload(rs::frame &frame)
Definition: example.hpp:171
void upload(rs::device &dev, rs::stream stream)
Definition: example.hpp:150
Frame.
Definition: rs.hpp:392
double next_time
Definition: example.hpp:66
static int stb_easy_font_width(char *text)
const char * rs_format_to_string(rs_format format)
Definition: rs.cpp:755
GLint GLint GLsizei width
Definition: glext.h:112
double get_timestamp() const
Definition: rs.hpp:426
int get_bpp() const
Retrieves bits per pixel.
Definition: rs.hpp:524
rs_device * dev
void draw_text(int x, int y, const char *text)
Definition: example.hpp:46
void make_depth_histogram(uint8_t rgb_image[640 *480 *3], const uint16_t depth_image[], int width, int height)
Definition: example.hpp:10
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: glext.h:112
GLuint get_gl_handle() const
Definition: example.hpp:71
void show(const void *data, int width, int height, rs::format format, const std::string &caption, int rx, int ry, int rw, int rh)
Definition: example.hpp:260
GLint GLint GLint GLint GLint x
Definition: glext.h:114
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:726
void upload(const void *data, int width, int height, rs::format format, int stride=0)
Definition: example.hpp:73
typedef GLuint(APIENTRYP PFNGLCREATEPROGRAMPROC)(void)


librealsense
Author(s): Sergey Dorodnicov , Mark Horn , Reagan Lopez
autogenerated on Fri Mar 13 2020 03:16:17