Easy3D 2.6.1
Loading...
Searching...
No Matches
Tutorial_202_Viewer_imgui/main.cpp

This example shows how to enhance the default Easy3D viewer with menus using ImGui.

The header file of the viewer class:

1/********************************************************************
2 * Copyright (C) 2015 Liangliang Nan <liangliang.nan@gmail.com>
3 * https://3d.bk.tudelft.nl/liangliang/
4 *
5 * This file is part of Easy3D. If it is useful in your research/work,
6 * I would be grateful if you show your appreciation by citing it:
7 * ------------------------------------------------------------------
8 * Liangliang Nan.
9 * Easy3D: a lightweight, easy-to-use, and efficient C++ library
10 * for processing and rendering 3D data.
11 * Journal of Open Source Software, 6(64), 3255, 2021.
12 * ------------------------------------------------------------------
13 *
14 * Easy3D is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License Version 3
16 * as published by the Free Software Foundation.
17 *
18 * Easy3D is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ********************************************************************/
26
27#ifndef EASY3D_TUTORIAL_VIEWER_IMGUI_H
28#define EASY3D_TUTORIAL_VIEWER_IMGUI_H
29
30
31#include <easy3d/viewer/viewer.h>
32
33
34
35// A very good tutorial for imgui:
36// https://eliasdaler.github.io/using-imgui-with-sfml-pt1/
37// https://eliasdaler.github.io/using-imgui-with-sfml-pt2/
38
39
40struct ImGuiContext;
41
42
43namespace easy3d {
44
45 class ViewerImGui : public Viewer
46 {
47 public:
61 explicit ViewerImGui(
62 const std::string& title = "Easy3D ViewerImGui",
63 int samples = 4,
64 int gl_major = 3, // must >= 3
65 int gl_minor = 2, // must >= 2
66 bool full_screen = false,
67 bool resizable = true,
68 int depth_bits = 24,
69 int stencil_bits = 8,
70 int width = 800,
71 int height = 600
72 );
73
77 ~ViewerImGui() override;
78
79 protected:
80
81 // imgui plugins
82 void init() override;
83
84 // draw the widgets
85 void pre_draw() override;
86
87 // the widgets
88 void post_draw() override;
89
90 void post_resize(int w, int h) override;
91
92 bool callback_event_cursor_pos(double x, double y) override;
93 bool callback_event_mouse_button(int button, int action, int modifiers) override;
94 bool callback_event_keyboard(int key, int action, int modifiers) override;
95 bool callback_event_character(unsigned int codepoint) override;
96 bool callback_event_scroll(double dx, double dy) override;
97
98 void draw_menu_file();
99 void draw_menu_view();
100
101 protected:
102 // Ratio between the framebuffer size and the window size.
103 // May be different from the DPI scaling!
104 float pixel_ratio();
105
106 float widget_scaling() { return dpi_scaling() / pixel_ratio(); }
107
108 // We don't need a per-window font. So this function is static
109 void reload_font(int font_size = 16);
110
111 protected:
112 // Single global context by default, but can be overridden by the user
113 static ImGuiContext * context_;
114
115 float menu_height_;
116 };
117
118}
119
120#endif // EASY3D_TUTORIAL_VIEWER_IMGUI_H
Definition collider.cpp:182

The source file of viewer class:

1/********************************************************************
2 * Copyright (C) 2015 Liangliang Nan <liangliang.nan@gmail.com>
3 * https://3d.bk.tudelft.nl/liangliang/
4 *
5 * This file is part of Easy3D. If it is useful in your research/work,
6 * I would be grateful if you show your appreciation by citing it:
7 * ------------------------------------------------------------------
8 * Liangliang Nan.
9 * Easy3D: a lightweight, easy-to-use, and efficient C++ library
10 * for processing and rendering 3D data.
11 * Journal of Open Source Software, 6(64), 3255, 2021.
12 * ------------------------------------------------------------------
13 *
14 * Easy3D is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License Version 3
16 * as published by the Free Software Foundation.
17 *
18 * Easy3D is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ********************************************************************/
26
27#include "viewer.h"
28
29#include <easy3d/util/file_system.h>
30#include <easy3d/core/point_cloud.h>
31#include <easy3d/core/surface_mesh.h>
32#include <easy3d/renderer/text_renderer.h>
33#include <easy3d/renderer/camera.h>
34
35#include <3rd_party/glfw/include/GLFW/glfw3.h> // for glfw functions
36
37#include <3rd_party/imgui/misc/fonts/imgui_fonts_droid_sans.h>
38#include <3rd_party/imgui/imgui.h>
39#include <3rd_party/imgui/backends/imgui_impl_glfw.h>
40#include <3rd_party/imgui/backends/imgui_impl_opengl3.h>
41
42
43namespace easy3d {
44
45 // \cond
46
47 ImGuiContext* ViewerImGui::context_ = nullptr;
48
49 ViewerImGui::ViewerImGui(
50 const std::string& title /* = "Easy3D ImGui Viewer" */,
51 int samples /* = 4 */,
52 int gl_major /* = 3 */,
53 int gl_minor /* = 2 */,
54 bool full_screen /* = false */,
55 bool resizable /* = true */,
56 int depth_bits /* = 24 */,
57 int stencil_bits /* = 8 */,
58 int width /* = 960 */,
59 int height /* = 800 */
60 ) : Viewer(title, samples, gl_major, gl_minor, full_screen, resizable, depth_bits, stencil_bits, width, height)
61 {
62#if defined(_WIN32) && defined(_MSC_VER)
63 // Liangliang: the internal glfw won't be shared across dll boundaries (But seems ok on macOS. That is weird!)
64 // see https://github.com/LiangliangNan/Easy3D/issues/178
65 glfwInit();
66#endif
67 }
68
69
70 ViewerImGui::~ViewerImGui() {
71 ImGui_ImplOpenGL3_Shutdown();
72 ImGui_ImplGlfw_Shutdown();
73
74 ImGui::DestroyContext(context_);
75
76 // Not needed: it will be called in the destructor of the base class
77 //Viewer::cleanup();
78 }
79
80
81 void ViewerImGui::init() {
82 Viewer::init();
83
84 if (!context_) {
85 // Setup ImGui binding
86 IMGUI_CHECKVERSION();
87
88 context_ = ImGui::CreateContext();
89
90 const char* glsl_version = "#version 150";
91 ImGui_ImplGlfw_InitForOpenGL(window_, true);
92 ImGui_ImplOpenGL3_Init(glsl_version);
93 ImGuiIO& io = ImGui::GetIO();
94 io.WantCaptureKeyboard = true;
95 io.WantTextInput = true;
96 io.IniFilename = nullptr;
97 ImGui::StyleColorsLight();
98 ImGuiStyle& style = ImGui::GetStyle();
99 style.FrameRounding = 5.0f;
100
101 // load font
102 reload_font();
103 }
104 }
105
106
107 float ViewerImGui::pixel_ratio() {
108 // Computes pixel ratio for hidpi devices
109 int fw = framebuffer_width();
110 int vw = width();
111 return static_cast<float>(fw) / static_cast<float>(vw);
112 }
113
114
115 void ViewerImGui::reload_font(int font_size)
116 {
117 ImGuiIO& io = ImGui::GetIO();
118 io.Fonts->Clear();
119 io.Fonts->AddFontFromMemoryCompressedTTF(droid_sans_compressed_data, droid_sans_compressed_size, static_cast<float>(font_size) * dpi_scaling());
120 io.FontGlobalScale = 1.0f / pixel_ratio();
121 ImGui_ImplOpenGL3_DestroyDeviceObjects();
122 }
123
124
125 void ViewerImGui::post_resize(int w, int h) {
126 Viewer::post_resize(w, h);
127 if (context_) {
128 ImGui::GetIO().DisplaySize.x = float(w);
129 ImGui::GetIO().DisplaySize.y = float(h);
130 }
131 }
132
133
134 bool ViewerImGui::callback_event_cursor_pos(double x, double y) {
135 if (ImGui::GetIO().WantCaptureMouse)
136 return true;
137 return Viewer::callback_event_cursor_pos(x, y);
138 }
139
140
141 bool ViewerImGui::callback_event_mouse_button(int button, int action, int modifiers) {
142 if (ImGui::GetIO().WantCaptureMouse)
143 return true;
144 return Viewer::callback_event_mouse_button(button, action, modifiers);
145 }
146
147
148 bool ViewerImGui::callback_event_keyboard(int key, int action, int modifiers) {
149 if (ImGui::GetIO().WantCaptureKeyboard)
150 return true;
151 return Viewer::callback_event_keyboard(key, action, modifiers);
152 }
153
154
155 bool ViewerImGui::callback_event_character(unsigned int codepoint) {
156 if (ImGui::GetIO().WantCaptureKeyboard)
157 return true;
158 return Viewer::callback_event_character(codepoint);
159 }
160
161
162 bool ViewerImGui::callback_event_scroll(double dx, double dy) {
163 if (ImGui::GetIO().WantCaptureMouse)
164 return true;
165 return Viewer::callback_event_scroll(dx, dy);
166 }
167
168
169 void ViewerImGui::pre_draw() {
170 ImGui_ImplGlfw_NewFrame();
171 ImGui_ImplOpenGL3_NewFrame();
172 ImGui::NewFrame();
173
174 Viewer::pre_draw();
175 }
176
177
178 void ViewerImGui::post_draw() {
179 static bool show_about = false;
180 if (show_about) {
181 ImGui::SetNextWindowPos(ImVec2(static_cast<float>(width()) * 0.5f, static_cast<float>(height()) * 0.5f), ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
182 ImGui::Begin("About Easy3D ImGui Viewer", &show_about, ImGuiWindowFlags_NoResize);
183 ImGui::Text("This viewer shows how to use ImGui for GUI creation and event handling");
184 ImGui::Separator();
185 ImGui::Text(
186 "\n"
187 "Liangliang Nan\n"
188 "liangliang.nan@gmail.com\n"
189 "https://3d.bk.tudelft.nl/liangliang/\n"
190 );
191 ImGui::End();
192 }
193
194 ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(5, 8));
195 if (ImGui::BeginMainMenuBar())
196 {
197 draw_menu_file();
198 draw_menu_view();
199
200 if (ImGui::BeginMenu("Help")) {
201 ImGui::MenuItem("About", nullptr, &show_about);
202 ImGui::EndMenu();
203 }
204 menu_height_ = ImGui::GetWindowHeight();
205 ImGui::EndMainMenuBar();
206 }
207 ImGui::PopStyleVar();
208
209 ImGui::Render();
210 ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
211
212 // workaround to draw the Easy3D logo and framerate at a different location (due to the menu bar)
213 auto show_logo = show_easy3d_logo_;
214 auto show_fps = show_frame_rate_;
215 show_easy3d_logo_ = false;
216 show_frame_rate_ = false;
217 Viewer::post_draw();
218 show_easy3d_logo_ = show_logo;
219 show_frame_rate_ = show_fps;
220
221 // draw Easy3D logo (on the right side)
222 if (texter_) {
223 const float font_size = 15.0f;
224 const float offset_x = (width() - texter_->string_width("Easy3D", font_size) - 50.0f) * dpi_scaling();
225 if (show_easy3d_logo_) {
226 const float offset_y = (20.0f + menu_height_) * dpi_scaling();
227 texter_->draw("Easy3D", offset_x, offset_y, font_size, 0);
228 }
229
230 // draw the framerate
231 if (show_frame_rate_) {
232 const float offset_y = (50.0f + menu_height_) * dpi_scaling();
233 texter_->draw(framerate_, offset_x, offset_y, font_size, 1);
234 }
235 }
236 }
237
238
239 void ViewerImGui::draw_menu_file() {
240 if (ImGui::BeginMenu("File"))
241 {
242 if (ImGui::MenuItem("Open", "Ctrl+O"))
243 open();
244 if (ImGui::MenuItem("Save As...", "Ctrl+S"))
245 save();
246
247 ImGui::Separator();
248 if (ImGui::MenuItem("Quit", "Alt+F4"))
249 glfwSetWindowShouldClose(window_, GLFW_TRUE);
250
251 ImGui::EndMenu();
252 }
253 }
254
255
256 void ViewerImGui::draw_menu_view() {
257 if (ImGui::BeginMenu("View"))
258 {
259 if (ImGui::MenuItem("Snapshot", nullptr))
260 snapshot();
261
262 ImGui::EndMenu();
263 }
264 }
265
266 // \endcond
267
268}
1/********************************************************************
2 * Copyright (C) 2015 Liangliang Nan <liangliang.nan@gmail.com>
3 * https://3d.bk.tudelft.nl/liangliang/
4 *
5 * This file is part of Easy3D. If it is useful in your research/work,
6 * I would be grateful if you show your appreciation by citing it:
7 * ------------------------------------------------------------------
8 * Liangliang Nan.
9 * Easy3D: a lightweight, easy-to-use, and efficient C++ library
10 * for processing and rendering 3D data.
11 * Journal of Open Source Software, 6(64), 3255, 2021.
12 * ------------------------------------------------------------------
13 *
14 * Easy3D is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License Version 3
16 * as published by the Free Software Foundation.
17 *
18 * Easy3D is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ********************************************************************/
26
27#include <easy3d/renderer/camera.h>
28#include <easy3d/util/resource.h>
29#include <easy3d/util/initializer.h>
30
31#include "viewer.h"
32
42
43
44using namespace easy3d;
45
46int main(int argc, char** argv) {
47 // initialize Easy3D.
48 initialize();
49
50 const std::string file_name = resource::directory() + "/data/easy3d.ply";
51 ViewerImGui viewer(EXAMPLE_TITLE);
52 viewer.camera()->setViewDirection(vec3(0, 0, -1));
53 viewer.camera()->setUpVector(vec3(0, 1, 0));
54
55 if (!viewer.add_model(file_name)) {
56 LOG(ERROR) << "failed to load model. Please make sure the file exists and format is correct.";
57 return EXIT_FAILURE;
58 }
59
60 return viewer.run();
61}
std::string directory()
Returns the resource directory (containing color maps, shaders, textures, fonts, etc....
Vec< 3, float > vec3
A 3D point/vector of float type.
Definition types.h:44
void initialize(bool info_to_stdout, bool use_log_file, bool use_setting_file, const std::string &resource_dir)
Initialization of Easy3D.
Definition initializer.cpp:39