-
Notifications
You must be signed in to change notification settings - Fork 253
/
Copy pathviewer.h
640 lines (549 loc) · 28.5 KB
/
viewer.h
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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
/********************************************************************
* Copyright (C) 2015 Liangliang Nan <[email protected]>
* https://3d.bk.tudelft.nl/liangliang/
*
* This file is part of Easy3D. If it is useful in your research/work,
* I would be grateful if you show your appreciation by citing it:
* ------------------------------------------------------------------
* Liangliang Nan.
* Easy3D: a lightweight, easy-to-use, and efficient C++ library
* for processing and rendering 3D data.
* Journal of Open Source Software, 6(64), 3255, 2021.
* ------------------------------------------------------------------
*
* Easy3D is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License Version 3
* as published by the Free Software Foundation.
*
* Easy3D is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
********************************************************************/
#ifndef EASY3D_VIEWER_VIEWER_H
#define EASY3D_VIEWER_VIEWER_H
#include <string>
#include <vector>
#include <memory>
#include <easy3d/core/types.h>
struct GLFWwindow;
namespace easy3d {
class Camera;
class Model;
class Drawable;
class LinesDrawable2D;
class TrianglesDrawable;
class TextRenderer;
class KeyFrameInterpolator;
/**
* @brief The built-in Easy3D viewer.
* @class Viewer easy3d/viewer/viewer.h
* @details Easy3D is really easy to use. That's why it has such a name.
* To use the viewer, simply create an instance of Viewer, and call the run() method, e.g.,
* \code
* MyViewer viewer("Example");
* viewer.run();
* \endcode
* The default Easy3D viewer can be easily extended by deriving your enhanced viewer from it
* by re-implementing some of its functions (see the documentation of Viewer).
*/
class Viewer
{
public:
/**
* @brief Constructor
* @param title The window title of the viewer, which can be changed by calling set_title() after construction.
* @param samples The number of samples for multisample antialiasing
* @param gl_major/gl_minor The OpenGL version to request. The created context will be
* compatible with the requested version (if the context creation succeeded).
* @param full_screen Do you want the viewer to be fullscreen?
* @param resizable Whether the viewer will be resizable by the user.
* @param depth_bits The desired bit depths of the depth component of the default framebuffer.
* @param stencil_bits The desired bit depths of the stencil component of the default framebuffer.
* @param width The width of the viewer, which can be changed by calling resize() after construction.
* @param height The height of the viewer, which can be changed by calling resize() after construction.
*/
explicit Viewer(
const std::string& title = "Easy3D Viewer",
int samples = 4,
int gl_major = 3, // must >= 3
int gl_minor = 2, // must >= 2
bool full_screen = false,
bool resizable = true,
int depth_bits = 24,
int stencil_bits = 8,
int width = 800,
int height = 600
);
/**
* @brief The destructor.
*/
virtual ~Viewer();
/**
* @brief Run the viewer.
* @param see_all See all contents within the screen? If true, the entire scene (i.e., all models) will be
* centered on the screen at a proper scale.
*/
int run(bool see_all = true);
/**
* @brief Terminate the viewer.
*/
virtual void exit();
/// @name Viewer properties
//@{
/**
* @brief Set the window title of the viewer.
* @param title The string of the title.
*/
void set_title(const std::string &title);
/**
* @brief Query the window title of the viewer.
* @return The string of the window title.
*/
const std::string& title() const { return title_; }
/**
* @brief Set/Change the viewer size.
* @param w/h The requested width/height (in pixels) of the viewer.
*/
void resize(int w, int h);
/// @brief Returns the width of the viewer/window.
int width() const { return width_; }
/// @brief Returns the height of the viewer/window.
int height() const { return height_; }
/// @brief Queries the size of the viewer/window.
void viewer_size(int& w, int& h) const { w = width_; h = height_; }
/// @brief Returns the width of the framebuffer, which is identical to: width() * dpi_scaling().
int framebuffer_width() const;
/// @brief Returns the height of the framebuffer, which is identical to: height() * dpi_scaling().
int framebuffer_height() const;
/// @brief Queries the size of the framebuffer.
void framebuffer_size(int& w, int& h) const;
/**
* @brief Sets the position of the content area of the viewer.
* @details This function sets the position, in screen coordinates, of the upper-left corner of the content
* area of the viewer. If the viewer is a full screen window, this function does nothing.
* @param xpos The x-coordinate of the upper-left corner of the content area.
* @param ypos The y-coordinate of the upper-left corner of the content area.
* @note This function must only be called from the main thread.
*/
void set_position(int xpos, int ypos);
/**
* @brief Query the actual samples of the viewer.
* @note The requested sample may not be supported by the context or graphics driver. This
* method returns the actual samples that the viewer supports.
*/
int samples() const { return samples_; }
/**
* @brief Query the scaling factor for high DPI devices (e.g., MackBook pro).
* @return The high DPI scaling factor.
*/
float dpi_scaling() const { return dpi_scaling_; }
/**
* @brief Set the background color of the viewer
* @param color The background color.
*/
void set_background_color(const easy3d::vec4& color) { background_color_ = color; }
/**
* @brief Query the background color of the viewer.
* @return The background color of the viewer
*/
const easy3d::vec4& background_color() const { return background_color_; }
/// @brief Returns the camera used by the viewer. See \c Camera.
Camera* camera() { return camera_.get(); }
/// @brief Returns the camera used by the viewer. See \c Camera.
const Camera* camera() const { return camera_.get(); }
//@}
/// @name File IO
//@{
/**
* @brief Open a model (PointCloud/SurfaceMesh/Graph) from a file into the viewer. On
* success, the viewer will be in charge of the memory management of the model.
* @details This method loads a model into the viewer. Internally, it will pop up a file
* dialog for the user to navigate to the file. After loading the model, the
* necessary drawables (e.g., "vertices" for point clouds, "faces" for surface
* meshes, and "edges" and "vertices" for graphs) will be created for visualization.
* @return true on success and false otherwise.
*/
virtual bool open();
/**
* @brief Save the active model (if exists) to a file.
* @details This method saves the active model to a file. Internally, it will pop up a file
* dialog for specifying the file name.
* @return true on success and false otherwise.
*/
virtual bool save() const;
//@}
/// @name Model management
//@{
/**
* @brief Add a model from a file to the viewer to be visualized. On success, the viewer
* will be in charge of the memory management of the model. The loaded model can be
* accessed by the 'current_model()' method.
* @details This method loads a model into the viewer. It allows the user to control if
* default drawables will be created. The default drawables are
* - for point clouds: "vertices".
* - for surface meshes: "faces", "vertices", "edges", "borders", and "locks".
* - for graphs: "vertices" and "edges".
* - polyhedral meshes: "faces:border", "faces:interior", "vertices", and "edges".
* These drawables are usually sufficient for basic rendering of the model. In case
* the default drawables don't meet the particular visualization purpose, you can
* set 'create_default_drawables' to false and create your needed drawables by
* calling model->renderer()->add_[type]_drawable(). Here the [type] must be one of
* "points", "lines", and "triangles'.
* @param file_name The string of the file name.
* @param create_default_drawables If true, the default drawables will be created.
* @return The pointer to the model added to the viewer (nullptr if failed).
* @related add_model(Model*, bool).
*/
virtual Model* add_model(const std::string& file_name, bool create_default_drawables = true);
/**
* @brief Add an existing model to the viewer to be visualized. On success, the viewer will
* be in charge of the memory management of the model.
* @details This method adds a model into the viewer. It allows the user to control if
* default drawables will be created. The default drawables are
* - for point clouds: "vertices".
* - for surface meshes: "faces", "vertices", "edges", "borders", and "locks".
* - for graphs: "vertices" and "edges".
* - polyhedral meshes: "faces:border", "faces:interior", "vertices", and "edges".
* These drawables are usually sufficient for basic rendering of the model. In case
* the default drawables don't meet the particular visualization purpose, you can
* set 'create_default_drawables' to false and create your needed drawables by
* calling model->renderer()->add_[type]_drawable(). Here the [type] must be one of
* "points", "lines", and "triangles'.
* @param model The pointer to the model.
* @param create_default_drawables If true, the default drawables will be created.
* @return The pointer to the model added to the viewer (nullptr if failed).
* @related add_model(const std::string&, bool).
*/
Model* add_model(std::shared_ptr<Model> model, bool create_default_drawables = true);
Model* add_model(Model* model, bool create_default_drawables = true);
/**
* @brief Delete a model. The memory of the model will be released and its existing drawables
* also be deleted.
* @param model The pointer to the model.
* @return True if the model has been deleted.
*/
virtual bool delete_model(Model* model);
/**
* @brief Query the models managed by this viewer.
* @return The models managed by this viewer.
*/
const std::vector< std::shared_ptr<Model> >& models() const { return models_; }
/**
* @brief Query the active model.
* @details The viewer can manage/visualize/process multiple models. The default behavior
* of the Easy3D viewer is, when a command is triggerred (e.g., the Save menu was
* clicked), only the active model is processed. This method is used to identify
* the active model.
* @return The active model.
*/
Model* current_model() const;
//@}
/// @name Drawable management
//@{
/**
* @brief Add a drawable to the viewer to be visualized. On success, the viewer will be in
* charge of the memory management of the drawable
* @details The use of drawables for visualization is quite flexible. Drawables are
* typically created for rendering 3D models (e.g., point clouds, meshes, graphs)
* and a 3D model is usually loaded from a file or generated by an algorithm. This
* method allows the user to visualize drawables without defining a 3D model.
* @param drawable The pointer to the drawable.
* @return The pointer of the drawable added to the viewer.
*/
Drawable* add_drawable(std::shared_ptr<Drawable> drawable);
Drawable* add_drawable(Drawable* drawable);
/**
* Delete the drawable from the viewer. The related drawables will also be deleted.
* @param drawable The pointer to the drawable.
* @return True if the drawable has been deleted.
*/
bool delete_drawable(Drawable* drawable);
/**
* @brief Query the drawables managed by this viewer.
* @return The drawables managed by this viewer.
*/
const std::vector< std::shared_ptr<Drawable> >& drawables() const { return drawables_; }
/**
* @brief Delete all visual contents of the viewer (all models and drawables).
*/
void clear_scene();
//@}
/// @name UI-related functions
//@{
/**
* @brief Update the display (i.e., repaint).
* @details This method is used to update the display of the rendering. Client should call
* it when your data/view is changed.
*/
void update() const;
/**
* @brief Moves the camera so that the entire scene or the active model is centered on the
* screen at a proper scale.
* @param model The pointer to the model to be centered on the screen. If nullptr, the
* entire scene (i.e., all models) will be centered on the screen at a proper scale.
*/
void fit_screen(const easy3d::Model* model = nullptr);
/**
* @brief Take a snapshot of the screen and save it to a file.
* @details This method takes a snapshot of the screen and saves the snapshot into an image file.
* Internally, it will pop up a file dialog for specifying the file name.
* @return true on success and false otherwise.
*/
virtual bool snapshot() const;
/**
* @brief Take a snapshot of the screen and save it to an image file. Supported image format: png, jpg, bmp, and tga.
* @details This function renders the scene into a framebuffer and takes a snapshot of the framebuffer.
* It allows the snapshot image to have a dimension different from the viewer, and it has no limit on the
* image size (if memory allows).
* @param file_name The image file name.
* @param scaling The scaling factor that determines the size of the image (default to 1.0, using the viewer size), i.e.,
* image_width = viewer_width * scaling;
* image_height = viewer_height * scaling;
* @param samples The required number of samples for antialiased rendering (which can be different from
* that of the default framebuffer). The default value is 4.
* @param back_ground Determines the background color. 0: current color; 1: white; 2: transparent.
* @param expand Expand the frustum to ensure the image aspect ratio.
* @return true on success and false otherwise.
*/
bool snapshot(const std::string& file_name, float scaling = 1.0f, int samples = 4, int back_ground = 1, bool expand = true) const;
/**
* @brief Query the XYZ coordinates of the surface point under the cursor.
* @param x The cursor x-coordinate, relative to the left edge of the content area.
* @param y The cursor y-coordinate, relative to the top edge of the content area.
* @param found indicates whether the point was found or not.
* @return The coordinates of the 3D point located at pixel (x,y) on screen. The returned point is valid only
* if found was returned true.
* @attention The screen point (x, y) is expressed in the screen coordinate system with an origin in the
* upper left corner. So it doesn't necessarily correspond to a pixel on High DPI devices, e.g., a
* Mac with a Retina display. If your inherited viewer uses a customized content area, you must also
* reimplement this function such that the x and y are relative to left and top edges of the content
* area, respectively.
* @note This method assumes that a GL context is available, and that its content was drawn using the Camera
* (i.e. using its projection and model-view matrices). This method hence cannot be used for offscreen
* Camera computations. Use cameraCoordinatesOf() and worldCoordinatesOf() to perform similar operations
* in that case. The precision of the method highly depends on the z-Buffer, i.e., how the zNear() and
* zFar() values are fitted to your scene. Loose boundaries will result in imprecision along the viewing
* direction.
*/
virtual vec3 point_under_pixel(int x, int y, bool &found) const;
/**
* @brief The usage information of the viewer.
* @param manual The manual of the viewer, to be shown in the console window. Using "default" will show the
* default shortcuts of the viewer.
* @param screen_hint The hint to the user, which will be sown in the top-left corner of the viewer.
* @attention The default shortcuts could be overridden by bind() function calls.
*/
void set_usage(const std::string& manual = "default", const std::string& screen_hint = "");
//@}
/// @name Algorithm execution
//@{
/**
* @brief The keys. Currently only a limited number of commonly used keys are supported.
*/
enum Key { // Do NOT modify the values!!!
// the unknown key
KEY_UNKNOWN = -1,
// the number keys
KEY_0 = 48, KEY_1 = 49, KEY_2 = 50, KEY_3 = 51, KEY_4 = 52, KEY_5 = 53, KEY_6 = 54, KEY_7 = 55,
KEY_8 = 56, KEY_9 = 57,
// the character keys
KEY_A = 65, KEY_B = 66, KEY_C = 67, KEY_D = 68, KEY_E = 69, KEY_F = 70, KEY_G = 71, KEY_H = 72,
KEY_I = 73, KEY_J = 74, KEY_K = 75, KEY_L = 76, KEY_M = 77, KEY_N = 78, KEY_O = 79, KEY_P = 80,
KEY_Q = 81, KEY_R = 82, KEY_S = 83, KEY_T = 84, KEY_U = 85, KEY_V = 86, KEY_W = 87, KEY_X = 88,
KEY_Y = 89, KEY_Z = 90,
// the functional keys
KEY_RIGHT = 262, KEY_LEFT = 263, KEY_DOWN = 264, KEY_UP = 265,
KEY_F1 = 290, KEY_F2 = 291, KEY_F3 = 292, KEY_F4 = 293, KEY_F5 = 294,
KEY_F6 = 295, KEY_F7 = 296, KEY_F8 = 297, KEY_F9 = 298,
// some printable keys
KEY_SPACE = 32,
KEY_COMMA = 44/* , */, KEY_MINUS = 45/* - */, KEY_PERIOD = 46/* . */,
KEY_SLASH = 47/* / */, KEY_SEMICOLON = 59/* ; */, KEY_EQUAL = 61/* = */,
KEY_LEFT_BRACKET = 91/* [ */, KEY_BACKSLASH = 92/* \ */, KEY_RIGHT_BRACKET = 93/* ] */
};
/**
* @brief The key modifiers. Currently only Shift, Ctrl, and Alt are supported.
*/
enum Modifier { /* Do NOT modify the values!!! */
MODIF_NONE = 0x0000,
MODIF_SHIFT = 0x0001,
#ifdef __APPLE__ // To have the same shortcut behavior on macOS and other platforms (i.e., Windows and Linux)
MODIF_CTRL = 0x0008,
#else
MODIF_CTRL = 0x0002,
#endif
MODIF_ALT = 0x0004
};
/**
* @brief Mouse buttons.
*/
enum Button { // Do NOT modify the values!!!
BUTTON_LEFT = 0,
BUTTON_RIGHT = 1,
BUTTON_MIDDLE = 2
};
/**
* A function type, which applies the user's algorithm(s)/operation(s) on the given model.
* @param viewer A pointer to this viewer.
* @param model The model to be operated on.
* Example of defining such a function:
* @code
* bool reconstruct(Viewer* viewer, Model* model) {
* auto cloud = dynamic_cast<PointCloud *>(model);
* auto mesh = surface_reconstruction(cloud);
* if (!mesh)
* return false;
* viewer->add_model(mesh);
* viewer->update();
* return true;
* }
* @endcode
*/
using Function = std::function<bool(Viewer* viewer, Model* model)>;
/**
* @brief Bind a function that will be triggered by the shortcut 'modifier + key'.
* @details This operation will overwrite the previous function (if exist) bound to the same key-modifier shortcut.
* @param func The function to be executed, which will be triggered by the shortcut.
* @param model The model to be processed.
* @param key The shortcut key.
* @param modifier The shortcut key modifier (e.g., Ctrl, Shift, Alt). This can be MODIF_NONE.
* @sa Function
*/
void bind(const Function& func, Model* model, Key key, Modifier modifier = MODIF_NONE) {
commands_[key][modifier] = std::make_pair(func, model);
}
//@}
/// @name Animation
//@{
/// @brief Function called at an equal interval for animation.
std::function<bool(Viewer* viewer)> animation_func_;
/// @brief Enable/Disable animation.
/// @attention To have animation, \c animation_func_ must be provided to specify how scene geometry is modified.
void set_animation(bool b);
/// @brief Is animation currently being performed.
bool is_animating() const;
//@}
protected:
// rendering. Users can put their additional rendering function here by reimplementing it.
virtual void draw() const;
// OpenGL resources (e.g., shaders, textures, VAOs) must be created when
// there exists a valid rendering context. It is (usually) a bad idea to do
// this in a constructor because the OpenGL context may not have been
// created yet or the visible one is not *current*. This init() function is
// to ensure you have a valid rendering context. It will be called before
// the draw procedure. See also cleanup().
// NOTE: Don't forget to call Viewer::init() at the beginning of your
// inherited function.
virtual void init();
// To destroy OpenGL resources (e.g., shaders, textures, VAOs), there must exist a valid rendering context.
// It is (usually) a bad idea to clean up OpenGL in a destructor because the OpenGL context may not exist
// (e.g., destroyed already) or the visible one is not *current*. This cleanup() function is to ensure you
// have a valid rendering context. See also init().
// NOTE: Don't forget to call Viewer::cleanup() at the end of your inherited function.
void cleanup();
// This function will be called before the main draw procedure.
virtual void pre_draw();
// This function draws axes of the coordinate system, Easy3D logo, frame rate, etc. overlaid on the scene.
// It will be called after the main draw procedure.
virtual void post_draw();
// External resize due to user interaction.
// This function will be called after the window size being changed.
// w/h: the new width and height of the viewer (not framebuffer, not viewport)
virtual void post_resize(int w, int h) { (void)w, (void)h; }
// Mouse button press event handler
virtual bool mouse_press_event(int x, int y, int button, int modifiers);
// Mouse button release event handler
virtual bool mouse_release_event(int x, int y, int button, int modifiers);
// Mouse drag (i.e., a mouse button was pressed) event handler
virtual bool mouse_drag_event(int x, int y, int dx, int dy, int button, int modifiers);
// Mouse free move (i.e., no mouse button was pressed) event handler
virtual bool mouse_free_move_event(int x, int y, int dx, int dy, int modifiers);
// Mouse scroll event handler
virtual bool mouse_scroll_event(int x, int y, int dx, int dy);
// Text input event handler: codepoint is native endian UTF-32 format
// NOTE: This one reveals the actual character being sent (not just the physical key)
virtual bool char_input_event(unsigned int codepoint);
// Keyboard event handler.
// NOTE: This function does not reveal the actual character.
virtual bool key_press_event(int key, int modifiers);
virtual bool key_release_event(int key, int modifiers);
// Handle a file drop event
virtual bool drop_event(const std::vector<std::string> & filenames);
// Handle a focus change event
virtual bool focus_event(bool focused);
protected:
GLFWwindow *create_window(const std::string &title,
int samples,
int gl_major, // must >= 3
int gl_minor, // must >= 2
bool full_screen,
bool resizable,
int depth_bits,
int stencil_bits,
int width,
int height);
void setup_callbacks(GLFWwindow*);
/* Event handlers. Client code should not touch these */
virtual bool callback_event_cursor_pos(double x, double y);
virtual bool callback_event_mouse_button(int button, int action, int modifiers);
virtual bool callback_event_keyboard(int key, int action, int mods);
virtual bool callback_event_character(unsigned int codepoint);
virtual bool callback_event_drop(int count, const char **filenames);
virtual bool callback_event_scroll(double dx, double dy);
virtual void callback_event_resize(int w, int h);
void draw_corner_axes() const;
void draw_face_labels(Model* model, TextRenderer* texter, int font_id, const vec3& color) const;
void draw_vertex_labels(Model* model, TextRenderer* texter, int font_id, const vec3& color) const;
void copy_view();
void paste_view();
protected:
GLFWwindow* window_;
bool should_exit_;
float dpi_scaling_;
int width_;
int height_;
std::string title_;
std::unique_ptr<Camera> camera_;
std::unique_ptr<KeyFrameInterpolator> kfi_;
bool is_animating_;
std::string manual_;
std::string hint_; // shown in the top-left corner of the screen
int samples_; // the actual samples
bool full_screen_;
vec4 background_color_;
// enable/disable event processing
bool process_events_;
char framerate_[48]; // show the frame rate
std::unique_ptr<TextRenderer> texter_;
bool show_easy3d_logo_;
// mouse
int pressed_button_; // for mouse drag
int modifiers_; // for mouse drag
bool drag_active_; // for mouse drag
int mouse_current_x_; // for mouse button and scroll events
int mouse_current_y_;
int mouse_pressed_x_; // last pressed position
int mouse_pressed_y_;
int pressed_key_;
bool show_pivot_point_;
bool show_frame_rate_;
//----------------- viewer data -------------------
// corner axes
std::unique_ptr<TrianglesDrawable> drawable_axes_;
// pivot cross
std::unique_ptr<LinesDrawable2D> drawable_pivot_;
// camera path
bool show_camera_path_;
std::vector< std::shared_ptr<Model> > models_;
int model_idx_;
// drawables independent of any model
std::vector< std::shared_ptr<Drawable> > drawables_;
typedef std::pair<Function, Model*> FunctionModel;
std::map<Key, std::map<Modifier, FunctionModel> > commands_;
};
}
#endif // EASY3D_VIEWER_VIEWER_H