-
Notifications
You must be signed in to change notification settings - Fork 4.8k
/
example-imgui.hpp
210 lines (172 loc) · 8.12 KB
/
example-imgui.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2021 Intel Corporation. All Rights Reserved.
#pragma once
#include <string>
#include <cmath>
#include <map>
#include "example.hpp"
#include <imgui.h>
#include <imgui_impl_glfw.h>
//////////////////////////////
// ImGui Helpers //
//////////////////////////////
//slider for ImGui
class slider {
public:
slider(const char* name, int seq_id, float init_value, float min_value, float max_value, ImVec2 position, ImVec2 size) :
_name(name), _seq_id(seq_id), _value(init_value), _min_value(min_value), _max_value(max_value), _position(position), _size(size) {}
void virtual show()=0;
public:
const char* _name;
int _seq_id;
float _value;
float _max_value;
float _min_value;
ImVec2 _position;
ImVec2 _size;
};
class hdr_slider : public slider {
public:
hdr_slider(const char* name, int seq_id, float init_value, rs2::sensor& sensor,
rs2_option option, rs2::option_range range, ImVec2 position, ImVec2 size) : slider(name, seq_id, init_value, range.min, range.max, position, size),
_sensor(sensor), _option(option), _range(range){}
void show() override
{
ImGui::SetNextWindowSize(_size);
ImGui::SetNextWindowPos(_position);
//concate the name given with seq_id in order to make a unique name (uniqeness is needed for Begin())
std::string name_id = std::string(_name) + std::to_string(_seq_id);
ImGui::Begin(name_id.c_str(), nullptr, _sliders_flags);
ImGui::Text("%s",_name);
bool is_changed =
ImGui::SliderFloat("", &_value, _min_value, _max_value, "%.3f", 5.0f, false); //5.0f for logarithmic scale
if (is_changed) {
_sensor.set_option(RS2_OPTION_SEQUENCE_ID, float(_seq_id));
_sensor.set_option(_option, _value);
}
ImGui::End();
}
public:
rs2::sensor& _sensor;
rs2_option _option;
rs2::option_range _range;
//flags for the sliders
const static int _sliders_flags = ImGuiWindowFlags_NoCollapse
| ImGuiWindowFlags_NoScrollbar
| ImGuiWindowFlags_NoSavedSettings
| ImGuiWindowFlags_NoResize
| ImGuiWindowFlags_NoMove
| ImGuiWindowFlags_NoTitleBar
| ImGuiWindowFlags_NoBringToFrontOnFocus;
};
//text box for ImGui
class text_box {
public:
text_box(const char* name, ImVec2 position, ImVec2 size) : _name(name), _position(position), _size(size) {}
void show(const char* text)
{
ImGui::SetNextWindowSize(_size);
ImGui::SetNextWindowPos(_position);
ImGui::Begin(_name, nullptr, _text_box_flags);
ImGui::Text("%s",text);
ImGui::End();
}
void remove_title_bar() {
_text_box_flags |= ImGuiWindowFlags_NoTitleBar;
}
public:
const char* _name;
ImVec2 _position;
ImVec2 _size;
// flags for displaying text box
int _text_box_flags = ImGuiWindowFlags_NoCollapse
| ImGuiWindowFlags_NoScrollbar
| ImGuiWindowFlags_NoSavedSettings
| ImGuiWindowFlags_NoResize
| ImGuiWindowFlags_NoMove
| ImGuiWindowFlags_NoFocusOnAppearing
| ImGuiWindowFlags_AlwaysUseWindowPadding
| ImGuiWindowFlags_NoBringToFrontOnFocus
| ImGuiWindowFlags_AlwaysAutoResize;
};
class hdr_widgets {
public:
// c'tor that creats all 4 sliders and text boxes
// needed to init in an init list because no default c'tor for sliders and they are allocated inside hdr_widgets
hdr_widgets(rs2::depth_sensor& depth_sensor):
_exposure_slider_seq_1("Exposure", 1, 8000,
depth_sensor, RS2_OPTION_EXPOSURE, depth_sensor.get_option_range(RS2_OPTION_EXPOSURE), { 130, 180 }, { 350, 40 }),
_exposure_slider_seq_2("Exposure", 2, 18,
depth_sensor, RS2_OPTION_EXPOSURE, depth_sensor.get_option_range(RS2_OPTION_EXPOSURE), { 390, 180 }, { 350, 40 }),
_gain_slider_seq_1("Gain", 1, 25,
depth_sensor, RS2_OPTION_GAIN, depth_sensor.get_option_range(RS2_OPTION_GAIN), { 130, 220 }, { 350, 40 }),
_gain_slider_seq_2("Gain", 2, 16,
depth_sensor, RS2_OPTION_GAIN, depth_sensor.get_option_range(RS2_OPTION_GAIN), { 390, 220 }, { 350, 40 }),
_text_box_hdr_explain("HDR Tutorial", { 120, 20 }, { 1000, 140 }),
_text_box_first_frame("frame 1", { 200, 150 }, { 170, 40 }),
_text_box_second_frame("frame 2", { 460, 150 }, { 170, 40 }),
_text_box_hdr_frame("hdr", { 850, 280 }, { 170, 40 })
{
// init frames map
//for initilize only - an empty frame with its properties
rs2::frame frame;
//set each frame with its properties:
// { tile's x coordinate, tiles's y coordinate, tile's width (in tiles), tile's height (in tiles), priority (default value=0) }, (x=0,y=0) <-> left bottom corner
//priority sets the order of drawing frame when two frames share part of the same tile,
//meaning if there are two frames: frame1 with priority=-1 and frame2 with priority=0, both with { 0,0,1,1 } as property,
//frame2 will be drawn on top of frame1
_frames_map[IR1] = frame_and_tile_property(frame, { 0,0,1,1,Priority::high });
_frames_map[IR2] = frame_and_tile_property(frame, { 1,0,1,1,Priority::high });
_frames_map[DEPTH1] = frame_and_tile_property(frame,{ 0,1,1,1,Priority::high });
_frames_map[DEPTH2] = frame_and_tile_property(frame, { 1,1,1,1,Priority::high });
_frames_map[HDR] = frame_and_tile_property(frame, { 2,0,2,2,Priority::high });
}
//show the features of the ImGui we have created
//we need slider 2 to be showen before slider 1 (otherwise slider 1 padding is covering slider 2)
void render_widgets() {
//start a new frame of ImGui
ImGui_ImplGlfw_NewFrame(1);
_exposure_slider_seq_2.show();
_exposure_slider_seq_1.show();
_gain_slider_seq_2.show();
_gain_slider_seq_1.show();
_text_box_first_frame.remove_title_bar();
_text_box_first_frame.show("Sequence 1");
_text_box_second_frame.remove_title_bar();
_text_box_second_frame.show("Sequence 2");
_text_box_hdr_frame.remove_title_bar();
_text_box_hdr_frame.show("HDR Stream");
_text_box_hdr_explain.show("This demo provides a quick overview of the High Dynamic Range (HDR) feature.\nThe HDR configures and operates on sequences of two frames configurations, for which separate exposure and gain values are defined.\nBoth configurations are streamed and the HDR feature uses both frames in order to provide the best depth image.\nChange the values of the sliders to see the impact on the HDR Depth Image.");
//render the ImGui features: sliders and text
ImGui::Render();
}
// return a reference to frames map
frames_mosaic& get_frames_map() {
return _frames_map;
}
void update_frames_map(const rs2::video_frame& infrared_frame, const rs2::frame& depth_frame,
const rs2::frame& hdr_frame, rs2_metadata_type hdr_seq_id, rs2_metadata_type hdr_seq_size) {
// frame index in frames_map are according to hdr_seq_id and hdr_seq_size
int infrared_index = int(hdr_seq_id);
int depth_index = int(hdr_seq_id + hdr_seq_size);
int hdr_index = int(hdr_seq_id + hdr_seq_size + 1);
//work-around, 'get_frame_metadata' sometimes (after changing exposure or gain values) sets hdr_seq_size to 0 even though it 2 for few frames
//so we update the frames only if hdr_seq_size > 0. (hdr_seq_size==0 <-> frame is invalid)
if (hdr_seq_size > 0) {
_frames_map[infrared_index].first = infrared_frame;
_frames_map[depth_index].first = depth_frame;
_frames_map[hdr_index].first = hdr_frame; //HDR shall be after IR1/2 & DEPTH1/2
}
}
public:
frames_mosaic _frames_map;
hdr_slider _exposure_slider_seq_1;
hdr_slider _gain_slider_seq_1;
hdr_slider _exposure_slider_seq_2;
hdr_slider _gain_slider_seq_2;
text_box _text_box_hdr_explain;
text_box _text_box_first_frame;
text_box _text_box_second_frame;
text_box _text_box_hdr_frame;
enum frame_id { IR1, IR2, DEPTH1, DEPTH2, HDR };
};