15 #pragma comment(lib, "opengl32.lib") 17 template<
typename T>
inline T
MIN(T
x, T
y) {
return x < y ? x :
y; }
18 template<
typename T>
inline T
MAX(T
x, T
y) {
return x > y ? x :
y; }
25 rect shrink(
int amt)
const {
return{ x0 + amt, y0 + amt, x1 - amt, y1 - amt }; }
31 for (std::string::size_type i = 0; (i = source.find(find, i)) != std::string::npos;)
33 source.replace(i, find.length(), replace);
34 i += replace.length();
45 gui() : scroll_vec({ 0, 0 }), click(), mouse_down(), clicked_id() {}
50 va_start(args, format);
52 vsnprintf(buffer,
sizeof(buffer), format, args);
55 glColor3f(c.
r, c.
g, c.
b);
75 #define STRING_CASE(S, C) std::string S = #S; if (s.compare(0, S.length(), S) == 0) { newC = C; s = find_and_replace(s, S + " ", ""); } 76 color color1 = { 0.6f, 1.0f, 1.0f };
77 color color2 = { 1.0f, 0.6f, 1.0f };
78 color color3 = { 1.0f, 1.0f, 0.6f };
79 color color4 = { 1.0f, 0.6f, 0.6f };
80 color color5 = { 0.6f, 0.6f, 1.0f };
81 color color6 = { 0.6f, 1.0f, 0.6f };
88 if (!enabled) newC = { 0.5f, 0.5f, 0.5f };
91 label(p, newC, s.c_str());
95 std::stringstream sstream;
96 sstream <<
": " << *
value;
98 label(newP, c, sstream.str().c_str());
101 rect bbox{ p.
x - 15, p.
y - 10, p.
x +
w + 10, p.
y + 5 };
102 if (bbox.contains(cursor))
106 fill_rect({ cursor.
x - hint_w - 7, cursor.
y + 5, cursor.
x + 7, cursor.
y - 17 }, { 1.0f, 1.0f, 1.0f });
107 fill_rect({ cursor.
x - hint_w - 6, cursor.
y + 4, cursor.
x + 6, cursor.
y - 16 }, { 0.0f, 0.0f, 0.0f });
108 label({ cursor.
x - hint_w, cursor.
y - 2 }, { 1.f, 1.f, 1.f }, hint.c_str());
115 glColor3f(c.
r, c.
g, c.
b);
116 glVertex2i(r.
x0, r.
y0);
117 glVertex2i(r.
x0, r.
y1);
118 glVertex2i(r.
x1, r.
y1);
119 glVertex2i(r.
x1, r.
y0);
125 glPushAttrib(GL_ENABLE_BIT);
127 glLineStipple(1, 0xAAAA);
128 glEnable(GL_LINE_STIPPLE);
130 glBegin(GL_LINE_STRIP);
131 glColor3f(c.
r, c.
g, c.
b);
132 glVertex2i(r.
x0, r.
y0);
133 glVertex2i(r.
x0, r.
y1);
134 glVertex2i(r.
x1, r.
y1);
135 glVertex2i(r.
x1, r.
y0);
136 glVertex2i(r.
x0, r.
y0);
144 fill_rect(r, { 1, 1, 1 });
145 fill_rect(r.
shrink(2), r.
contains(cursor) ? (mouse_down ?
color{ 0.3f, 0.3f, 0.3f } :
color{ 0.4f, 0.4f, 0.4f }) :
color{ 0.5f, 0.5f, 0.5f });
153 bool changed =
false;
159 fill_rect(r, { 1, 1, 1 });
160 fill_rect(r.
shrink(1), { 0.5, 0.5, 0.5 });
161 if (value) fill_rect(r.
shrink(3), { 1, 1, 1 });
165 bool slider(
int id,
const rect &
r,
double min,
double max,
double step,
double &
value,
bool disable_dragger =
false)
167 bool changed =
false;
169 double p = (w -
h) * (value - min) / (max - min);
170 if (mouse_down && clicked_id ==
id)
172 p = std::max(0.0, std::min<double>(cursor.
x - clicked_offset.
x - r.
x0, w -
h));
173 double new_value = min + p * (max - min) / (w -
h);
174 if (step) new_value = std::round((new_value - min) / step) * step + min;
175 changed = new_value !=
value;
177 p = (w -
h) * (value - min) / (max - min);
180 if (click && dragger.
contains(cursor) && !disable_dragger)
182 clicked_offset = { cursor.
x - dragger.
x0, cursor.
y - dragger.
y0 };
185 fill_rect(r, { 0.5, 0.5, 0.5 });
187 if (!disable_dragger)
188 fill_rect(dragger, { 1, 1, 1 });
195 value =
MAX(min,
MIN(max, value));
197 double p = (
w)* (value - min) / (max - min);
205 else if (value == min)
212 fill_rect(r, { 0.5, 0.5, 0.5 });
213 fill_rect(dragger, { 1, 1, 1 });
216 std::ostringstream oss;
217 oss << std::setprecision(2) << std::fixed << min;
218 auto delta = (min < 0) ? 40 : 22;
219 draw_text(r.
x0 - delta, r.
y1 + abs(
h / 2) + 3, oss.str().c_str());
222 oss << std::setprecision(2) << std::fixed << max;
226 oss << std::setprecision(2) << std::fixed <<
value;
227 draw_text(dragger.
x0 - 1, dragger.
y0 + 12, oss.str().c_str());
232 if (r.
contains(cursor)) offset -= scroll_vec.
y * 20;
233 offset = std::min(offset, client_height - (r.
y1 - r.
y0));
234 offset = std::max(offset, 0);
235 if (client_height <= r.
y1 - r.
y0)
return;
236 auto bar =
r; bar.x0 = bar.x1 - 10;
238 dragger.y0 = bar.y0 + offset * (r.
y1 - r.
y0) / client_height;
239 dragger.y1 = bar.y0 + (offset + r.
y1 - r.
y0) * (r.
y1 - r.
y0) / client_height;
240 fill_rect(bar, { 0.5, 0.5, 0.5 });
241 fill_rect(dragger, { 1, 1, 1 });
252 std::lock_guard<std::mutex> lock(
mm_mutex);
280 int close_win_width = 550;
281 int close_win_height = 150;
282 auto closeWin =
glfwCreateWindow(close_win_width, close_win_height, title.c_str(),
nullptr,
nullptr);
284 glfwSetWindowPos(closeWin, xpos + width / 2 - close_win_width / 2, ypos + height / 2 - close_win_height / 2);
306 data->g->click =
true;
317 glViewport(0, 0, w, h);
318 glClear(GL_COLOR_BUFFER_BIT);
322 glOrtho(0, w, h, 0, -1, +1);
325 size_t line_lenght = 80;
329 if (
message.size() < line_lenght)
331 g.label(p, { 1, 1, 1 },
message.c_str());
335 std::vector<std::string> str_vec;
339 size_t string_size = temp_message.size();
340 while (index < string_size)
342 if (index + line_lenght >= string_size)
344 str_vec.push_back(temp_message.substr(index));
348 auto curr_index = index + temp_message.substr(index, line_lenght).find_last_of(
' ');
350 str_vec.push_back(temp_message.substr(index, curr_index - index));
354 for (
auto& elem : str_vec)
356 g.label(p, { 1, 1, 1 }, elem.c_str());
364 if (
g.button({ w / 2 - 40, h - 40, w / 2 + 40, h - 10 },
" OK"))
371 if (!
g.mouse_down)
g.clicked_id = 0;
405 for (
auto& related : it->second)
407 auto opt_it = std::find_if(options.begin(), options.end(), [related](
option o) {
return related == o.opt; });
408 if (opt_it != options.end())
413 dev.
get_option_range(opt_it->opt, opt_it->min, opt_it->max, opt_it->step, opt_it->def);
425 for (
auto i = 0; i < 5; i++)
443 stream_name <<
"MOTION EVENTS";
478 int y = 2 * h / 3 + 5;
479 auto rect_y0_pos = y + 36;
480 auto rect_y1_pos = y + 28;
481 auto indicator_width = 42;
483 buffers[5].
print(x, rect_y0_pos - 10,
"Gyro X: ");
484 g.
indicator({ x + 100, rect_y0_pos, x + 300, rect_y1_pos }, -10, 10, m_gyro_data.
axes[0]);
485 rect_y0_pos += indicator_width;
486 rect_y1_pos += indicator_width;
488 buffers[5].
print(x, rect_y0_pos - 10,
"Gyro Y: ");
489 g.
indicator({ x + 100, rect_y0_pos, x + 300, rect_y1_pos }, -10, 10, m_gyro_data.
axes[1]);
490 rect_y0_pos += indicator_width;
491 rect_y1_pos += indicator_width;
493 buffers[5].
print(x, rect_y0_pos - 10,
"Gyro Z: ");
494 g.
indicator({ x + 100, rect_y0_pos, x + 300, rect_y1_pos }, -10, 10, m_gyro_data.
axes[2]);
495 rect_y0_pos += indicator_width;
496 rect_y1_pos += indicator_width;
498 buffers[5].
print(x, rect_y0_pos - 10,
"Acc X: ");
499 g.
indicator({ x + 100, rect_y0_pos, x + 300, rect_y1_pos }, -10, 10, m_acc_data.
axes[0]);
500 rect_y0_pos += indicator_width;
501 rect_y1_pos += indicator_width;
503 buffers[5].
print(x, rect_y0_pos - 10,
"Acc Y: ");
504 g.
indicator({ x + 100, rect_y0_pos, x + 300, rect_y1_pos }, -10, 10, m_acc_data.
axes[1]);
505 rect_y0_pos += indicator_width;
506 rect_y1_pos += indicator_width;
508 buffers[5].
print(x, rect_y0_pos - 10,
"Acc Z: ");
509 g.
indicator({ x + 100, rect_y0_pos, x + 300, rect_y1_pos }, -10, 10, m_acc_data.
axes[2]);
514 auto it = find_if(options.begin(), options.end(), [opt](
option o) {
return o.opt == opt; });
515 if (it == options.end())
return 0.0;
526 auto height = intrinsics.height;
543 int main(
int argc,
char * argv[])
550 std::atomic<bool> running(
true);
551 bool has_motion_module =
false;
553 std::vector<option> options;
561 std::map<rs::stream, resolution> resolutions;
563 std::vector<int> req_fps = { 30, 30, 30, 30, 60, 30 };
566 std::vector<w_h> wh = { { 0,0 }, { 640,480 }, { 0,0 }, { 0,0 }, { 640,480 }, {0,0}};
574 win =
glfwCreateWindow(1550, 960,
"CPP Configuration Example",
nullptr,
nullptr);
593 if (ctx.
get_device_count() < 1)
throw std::runtime_error(
"No device found. Is it plugged in?");
608 if (has_motion_module)
628 options.push_back(o);
635 std::stringstream ss;
637 std::cerr << ss.str();
641 catch (
const std::exception & e)
643 std::cerr << e.what() << std::endl;
649 std::cerr <<
"Unresolved error type during camera initialization" << std::endl;
650 show_message(win,
"Exception",
"Unresolved error type during camera initialization");
655 unsigned long long frame_number[streams] = {};
656 double frame_timestamp[streams] = {};
657 int fps[streams] = {};
658 double dc_preset = 0, iv_preset = 0;
659 int offset = 0, panel_height = 1;
660 int gui_click_flag = 0;
673 glViewport(0, 0, w, h);
674 glClear(GL_COLOR_BUFFER_BIT);
678 glOrtho(0, w, h, 0, -1, +1);
685 if (g.
button({ w - 260, y, w - 20, y + 24 },
"Stop Capture"))
690 for (
auto i = 0; i < 5; i++) frames_queue[i].clear();
703 if (g.
button({ w - 260, y, w - 20, y + 24 },
"Start Capture"))
705 std::vector<rs::stream> supported_streams;
709 for (
auto &
stream : supported_streams)
713 std::cout <<
"Capturing " <<
stream <<
" at " << intrin.
width <<
" x " << intrin.height;
714 std::cout << std::setprecision(1) << std::fixed <<
", fov = " << intrin.hfov() <<
" x " << intrin.vfov() <<
", distortion = " << intrin.model() << std::endl;
737 std::stringstream stream_name;
741 static bool is_callback_set =
false;
750 if (!is_callback_set || g.
checkbox({ w - 260, y, w - 240, y + 20 }, enable))
752 enable_stream(dev, i, formats[i], wh[i].width, wh[i].height, req_fps[i], enable, stream_name);
756 static const auto max_queue_size = 2;
757 for (
auto i = 0; i < 5; i++)
761 if (running && frames_queue[i].
size() < max_queue_size)
763 frames_queue[i].
enqueue(std::move(frame));
768 is_callback_set =
true;
770 g.
label({ w - 234, y + 13 }, { 1, 1, 1 },
"Enable %s", stream_name.str().c_str());
778 auto new_w = w + (has_motion_module ? 150 : -280);
780 int scale_factor = (has_motion_module ? 3 : 2);
781 int fWidth = new_w / scale_factor;
782 int fHeight = h / scale_factor;
784 static struct position {
int rx, ry, rw, rh; } pos_vec[5];
785 pos_vec[0] = position{ fWidth, 0, fWidth, fHeight };
786 pos_vec[1] = position{ 0, 0, fWidth, fHeight };
787 pos_vec[2] = position{ 0, fHeight, fWidth, fHeight };
788 pos_vec[3] = position{ fWidth, fHeight, fWidth, fHeight };
789 pos_vec[4] = position{ 0, 2 * fHeight, fWidth, fHeight };
790 position center_position = position{ 0, 0, fWidth * 2, fHeight * 2 };
792 bool g_clicked = g.
click;
793 static int frame_clicked[5] = {};
795 for (
auto i = 0; i < 5; i++)
800 if (frames_queue[i].try_dequeue(&frame))
809 if (g_clicked && gui_click_flag &&
810 g.
cursor.
x >= center_position.rx && g.
cursor.
x <= (center_position.rw + center_position.rx) &&
811 g.
cursor.
y >= center_position.ry && g.
cursor.
y <= (center_position.rh + center_position.ry))
813 pos_vec[i] = prev_pos;
814 gui_click_flag = !gui_click_flag;
815 for (
int j = 0; j < 5; ++j)
816 frame_clicked[j] =
false;
820 else if (g_clicked && !gui_click_flag &&
821 g.
cursor.
x >= pos_vec[i].rx && g.
cursor.
x <= (pos_vec[i].rw + pos_vec[i].rx) &&
822 g.
cursor.
y >= pos_vec[i].ry && g.
cursor.
y <= (pos_vec[i].rh + pos_vec[i].ry))
824 gui_click_flag = !gui_click_flag;
825 frame_clicked[i] = gui_click_flag;
829 if (frame_clicked[i])
831 prev_pos = pos_vec[i];
832 pos_vec[i] = center_position;
833 buffers[i].
show((
rs::stream)i, format[i], fps[i], frame_number[i], frame_timestamp[i], pos_vec[i].rx, pos_vec[i].ry, pos_vec[i].rw, pos_vec[i].rh, resolutions[(
rs::stream)i].
width, resolutions[(
rs::stream)i].
height);
835 else if (!gui_click_flag)
836 buffers[i].
show((
rs::stream)i, format[i], fps[i], frame_number[i], frame_timestamp[i], pos_vec[i].rx, pos_vec[i].ry, pos_vec[i].rw, pos_vec[i].rh, resolutions[(
rs::stream)i].
width, resolutions[(
rs::stream)i].
height);
838 if (frame_clicked[i])
840 else if (!gui_click_flag)
846 std::lock_guard<std::mutex> lock(
mm_mutex);
851 for (
auto & o : options)
868 auto is_checkbox = (o.min == 0) && (o.max == 1) && (o.step == 1);
869 auto is_checked = o.value > 0;
872 g.
checkbox({ w - 260, y + 10, w - 240, y + 30 }, is_checked) :
873 g.
slider((
int)o.opt + 1, { w - 260, y + 16, w - 20, y + 36 }, o.min, o.max, o.step, o.value))
875 if (is_checkbox) dev->
set_option(o.opt, is_checked ? 1 : 0);
883 if (is_checkbox) g.
option_label({ w - 230, y + 24 }, { 1, 1, 1 }, *
dev, o.opt, 210,
true);
884 else g.
option_label({ w - 260, y + 12 }, { 1, 1, 1 }, *
dev, o.opt, 240,
true, &o.value);
889 g.
label({ w - 260, y + 12 }, { 1, 1, 1 },
"Depth control parameters preset: %g", dc_preset);
892 g.
label({ w - 260, y + 12 }, { 1, 1, 1 },
"IVCAM options preset: %g", iv_preset);
896 panel_height = y + 10 +
offset;
906 for (
auto i = 0; i < streams; i++) frames_queue[i].clear();
911 for (
auto i = 0; i < streams; i++)
922 std::stringstream ss;
924 std::cerr << ss.str();
927 catch (
const std::exception & e)
929 std::cerr << e.what() << std::endl;
void log_to_console(log_severity min_severity)
Provides convenience methods relating to devices.
intrinsics get_stream_intrinsics(stream stream) const
Retrieves intrinsic camera parameters for specific stream.
static void rs_apply_ivcam_preset(rs_device *device, rs_ivcam_preset preset)
#define STRING_CASE(S, C)
void indicator(const rect &r, double min, double max, double value)
void enable_stream(stream stream, int width, int height, format format, int framerate, output_buffer_format output_buffer_type=output_buffer_format::continous)
Enables specific stream and requests specific properties.
rs_timestamp_data timestamp_data
void show_message(GLFWwindow *curr_window, const std::string &title, const std::string &message)
const char * rs_stream_to_string(rs_stream stream)
GLFWAPI void glfwGetWindowSize(GLFWwindow *window, int *width, int *height)
Retrieves the size of the client area of the specified window.
rs_event_source source_id
const std::string & get_failed_args() const
void on_timestamp_event(rs::timestamp_data entry)
void update_related_options(rs::device &dev, rs::option opt, std::vector< option > &options)
GLint GLint GLsizei GLsizei height
GLint GLint GLint GLint GLint GLint y
bool slider(int id, const rect &r, double min, double max, double step, double &value, bool disable_dragger=false)
GLuint GLsizei const GLchar * message
void get_option_range(option option, double &min, double &max, double &step)
Retrieves available range of values of supported option.
GLFWAPI void * glfwGetWindowUserPointer(GLFWwindow *window)
Returns the user pointer of the specified window.
GLsizei const GLchar *const * string
int get_stream_width(stream stream) const
Retrieves width, in pixels, of a specific stream, equivalent to the width field from the stream's int...
int main(int argc, char *argv[])
Motion data from gyroscope and accelerometer from the microcontroller.
bool button(const rect &r, const std::string &label)
rs::motion_data m_gyro_data
Exposes librealsense functionality for C++ compilers.
GLenum GLenum GLsizei const GLuint GLboolean enabled
void fill_rect(const rect &r, const color &c)
rs_option
Defines general configuration controls.
GLfloat GLfloat GLfloat GLfloat h
option
Defines general configuration controls.
struct GLFWwindow GLFWwindow
Opaque window object.
rect shrink(int amt) const
bool motion_tracking_enable
void stop(rs::source source=rs::source::video)
Ends streaming on all streams for this device.
GLFWAPI int glfwInit(void)
Initializes the GLFW library.
void show(float rx, float ry, float rw, float rh) const
GLFWAPI void glfwSetWindowUserPointer(GLFWwindow *window, void *pointer)
Sets the user pointer of the specified window.
static void rs_apply_depth_control_preset(rs_device *device, int preset)
void option_label(const int2 &p, const color &c, rs::device &dev, rs::option opt, double max_width, bool enabled, double *value=nullptr)
stream
Streams are different types of data provided by RealSense devices.
int get_stream_height(stream stream) const
Retrieves height, in pixels, of a specific stream, equivalent to the height field from the stream's i...
bool is_any_stream_enable(rs::device *dev)
bool is_stream_enabled(stream stream) const
Determines if specific stream is enabled.
void disable_motion_tracking(void)
Disables events polling.
format get_format() const
Retrieves frame format.
format
Formats: defines how each stream can be encoded. rs_format specifies how a frame is represented in me...
void print(int x, int y, const char *text)
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
void start(rs::source source=rs::source::video)
Begins streaming on all enabled streams for this device.
void enable_motion_tracking(std::function< void(motion_data)> motion_handler, std::function< void(timestamp_data)> timestamp_handler)
Sets callback for motion module event.
void draw_autoexposure_roi_boundary(rs::stream s, const std::vector< option > &options, rs::device *dev, gui &g, int x, int y, double w, double h)
GLFWAPI void glfwSwapBuffers(GLFWwindow *window)
Swaps the front and back buffers of the specified window.
GLFWAPI void glfwMakeContextCurrent(GLFWwindow *window)
Makes the context of the specified window current for the calling thread.
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * data
double get_option(option option)
Retrieves current value of single option.
GLFWAPI void glfwWindowHint(int target, int hint)
Sets the specified window hint to the desired value.
GLuint GLsizei const GLchar * label
bool contains(const int2 &p) const
int is_motion_tracking_active()
Checks if data acquisition is active.
int get_framerate() const
Returns configured frame rate.
void update_mm_data(texture_buffer *buffers, int w, int h, gui &g)
GLsizei const GLfloat * value
GLFWAPI void glfwSetWindowSize(GLFWwindow *window, int width, int height)
Sets the size of the client area of the specified window.
GLFWAPI void glfwSetWindowPos(GLFWwindow *window, int xpos, int ypos)
Sets the position of the client area of the specified window.
bool checkbox(const rect &r, bool &value)
GLboolean GLboolean GLboolean b
bool supports_option(option option) const
Determines if device allows specific option to be queried and set.
GLFWAPI GLFWwindow * glfwCreateWindow(int width, int height, const char *title, GLFWmonitor *monitor, GLFWwindow *share)
Creates a window and its associated context.
void disable_stream(stream stream)
Disables specific stream.
GLuint GLfloat GLfloat GLfloat x1
GLFWAPI void glfwGetWindowPos(GLFWwindow *window, int *xpos, int *ypos)
Retrieves the position of the client area of the specified window.
static int stb_easy_font_width(char *text)
rs_stream
Streams are different types of data provided by RealSense devices.
GLint GLint GLsizei width
rs::motion_data m_acc_data
static std::map< rs::option, std::vector< rs::option > > options_dependencies
const char * rs_option_to_string(rs_option option)
GLuint const GLchar * name
double get_timestamp() const
GLsizei GLsizei GLchar * source
void label(const int2 &p, const color &c, const char *format,...)
GLFWAPI void glfwDestroyWindow(GLFWwindow *window)
Destroys the specified window and its context.
GLFWAPI void glfwGetFramebufferSize(GLFWwindow *window, int *width, int *height)
Retrieves the size of the framebuffer of the specified window.
unsigned long long get_frame_number() const
void draw_text(int x, int y, const char *text)
GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow *window, GLFWwindowclosefun cbfun)
Sets the close callback for the specified window.
GLFWAPI void glfwTerminate(void)
Terminates the GLFW library.
GLuint GLfloat GLfloat y0
void enable_stream(rs::device *dev, int stream, rs::format format, int w, int h, int fps, bool enable, std::stringstream &stream_name)
void set_frame_callback(rs::stream stream, std::function< void(frame)> frame_handler)
Sets callback for frame arrival event.
GLFWAPI void glfwPollEvents(void)
Processes all pending events.
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
const char * get_option_description(option option)
Retrieves device-specific option description.
bool supports(capabilities capability) const
Determines device capabilities.
void vscroll(const rect &r, int client_height, int &offset)
bool is_streaming() const
Determines if device is currently streaming.
double find_option_value(const std::vector< option > &options, rs::option opt)
device * get_device(int index)
GLdouble GLdouble GLdouble GLdouble top
void set_option(option option, double value)
Sets current value of single option.
void outline_rect(const rect &r, const color &c)
void on_motion_event(rs::motion_data entry)
rs_ivcam_preset
For SR300 devices: provides optimized settings (presets) for specific types of usage.
const std::string & get_failed_function() const
Timestamp data from the motion microcontroller.
capabilities
Specifies various capabilities of a RealSense device.
GLdouble GLdouble GLdouble r
GLint GLint GLint GLint GLint x
GLubyte GLubyte GLubyte GLubyte w
std::string find_and_replace(std::string source, std::string const &find, std::string const &replace)
void upload(const void *data, int width, int height, rs::format format, int stride=0)
int get_device_count() const
GLFWAPI int glfwWindowShouldClose(GLFWwindow *window)
Checks the close flag of the specified window.