1 // Copyright 2016-2021 Doug Moen
2 // Licensed under the Apache License, version 2.0
3 // See accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0
4 
5 // Based on glslViewer, which is:
6 // Copyright 2014 Patricio Gonzalez Vivo
7 // Licensed under the 3-Clause BSD Licence:
8 // https://opensource.org/licenses/BSD-3-Clause
9 
10 #ifndef LIBCURV_VIEWER_VIEWER_H
11 #define LIBCURV_VIEWER_VIEWER_H
12 
13 #include <libcurv/render.h>
14 #include <libcurv/viewed_shape.h>
15 #include "shader.h"
16 #include "vbo.h"
17 #include <glm/glm.hpp>
18 
19 namespace curv {
20 struct Shape_Program;
21 
22 namespace viewer {
23 
24 struct Viewer_Config : public Render_Opts
25 {
26     bool verbose_ = false;
27     bool lazy_ = false;
28 };
29 
30 struct Viewer
31 {
32     /*--- PUBLIC API ---*/
33     Viewer();
34     Viewer(const Viewer_Config&);
35 
36     // Set the current shape. May be called at any time, before opening the
37     // window, or while the window is open.
38     void set_shape_no_hud(const Shape_Program&, const Render_Opts&);
39     void set_shape(Viewed_Shape);
40 
is_openViewer41     bool is_open() { return window_ != nullptr; }
42 
43     // Reset camera to initial position.
44 	enum viewtype {home,upside, downside, leftside, rightside, frontside, backside};
45     void reset_view(viewtype view);
46 
47     // Open window: initialize OpenGL, create the window. Idempotent.
48     void open();
49 
50     // Called repeatedly in a loop once the window is open.
51     // Returns false when it is time to exit the loop (user has closed window).
52     bool draw_frame();
53 
54     // Close window. Idempotent.
55     void close();
56 
57     ~Viewer();
58 
59     // Open a Viewer window on the current shape, and run until the window
60     // is closed by the user. It is equivalent to:
61     //     open();
62     //     while (draw_frame());
63     //     close();
64     void run();
65 
66     /*--- PARAMETER STATE, can set before window is opened ---*/
67     Viewer_Config config_;
68     glm::ivec2 window_size_{500, 500}; // initial window size
69     bool headless_{false};
70 
71     /*--- INTERNAL STATE ---*/
72 
73     Viewed_Shape shape_{};
74     Shader shader_{};
75     std::string vertSource_{};
76     GLFWwindow* window_ = nullptr;
77     bool have_window_pos_ = false;
78     glm::ivec2 window_pos_;
79     glm::ivec2 viewport_; // window size in screen coordinates
80     float fPixelDensity_ = 1.0;
81     Vbo* vbo_ = nullptr;
82     double current_time_ = 0.0;
83     struct {
84         double last_reported_ = 0.0;
85         double delta_time_ = 0.0;
86         unsigned frames_ = 0;
resetViewer::__anonfea1eb30010887         void reset() {
88             last_reported_ = glfwGetTime();
89             delta_time_ = 0.0;
90             frames_ = 0;
91         }
92     } fps_;
93     GLuint vao_; // a Vertex Array Object
94     bool hud_ = false;
95     bool error_ = false;
96     unsigned num_errors_ = 0;
97 
98     // The 2D camera position.
99     glm::mat3 u_view2d_ {};
100 
101     // The 3D camera position. See reset_view() for more information.
102     glm::vec3 u_centre3d_ {};
103     glm::vec3 u_eye3d_ {};
104     glm::vec3 u_up3d_ {};
105 
106     typedef struct {
107         float     x,y;
108         int       button;
109         glm::vec2 velocity;
110         glm::vec2 drag;
111     } Mouse;
112     Mouse mouse_;
113 
114     // INTERNAL FUNCTIONS
115     void initGL();
116     void setup();
117     void onKeyPress(int, int);
118     void onMouseMove(double, double);
119     void onScroll(float);
120     void onMouseDrag(float, float, int);
121     void render();
122     void swap_buffers();
123     void poll_events();
124     void measure_time();
125     void closeGL();
126     float getPixelDensity();
127     void onExit();
128     void setWindowSize(int, int);
129     int getWindowWidth();
130     int getWindowHeight();
131 };
132 
133 }} // namespace
134 #endif // header guard
135