1 // =============================================================================
2 // PROJECT CHRONO - http://projectchrono.org
3 //
4 // Copyright (c) 2014 projectchrono.org
5 // All rights reserved.
6 //
7 // Use of this source code is governed by a BSD-style license that can be found
8 // in the LICENSE file at the top level of the distribution and at
9 // http://projectchrono.org/license-chrono.txt.
10 //
11 // =============================================================================
12 // Authors: Hammad Mazhar, Radu Serban
13 // =============================================================================
14 // OpenGL window singleton, this class manages the opengl context and window
15 // =============================================================================
16 
17 #ifndef CHOPENGLWINDOW_H
18 #define CHOPENGLWINDOW_H
19 
20 #include "chrono_opengl/core/ChApiOpenGL.h"
21 #include "chrono_opengl/ChOpenGLViewer.h"
22 
23 namespace chrono {
24 
25 /// Namespace with classes for the Chrono::OpenGL module.
26 namespace opengl {
27 
28 /// @addtogroup opengl_module
29 /// @{
30 
31 /// Interface of an object which can receive events.
32 class CH_OPENGL_API ChOpenGLEventCB {
33   public:
~ChOpenGLEventCB()34     virtual ~ChOpenGLEventCB() {}
35 
36     /// GLFW callback to handle keyboard events.
37     /// Return 'true' if the event is completely done and no further processing is to occur.
38     virtual bool CallbackKeyboard(GLFWwindow* window, int key, int scancode, int action, int mode) = 0;
39 
40     /// GLFW callback to handle mouse button events.
41     /// Return 'true' if the event is completely done and no further processing is to occur.
42     virtual bool CallbackMouseButton(GLFWwindow* window, int button, int action, int mods) = 0;
43 
44     /// GLFW callback to handle events generated by changes in mouse position.
45     /// Return 'true' if the event is completely done and no further processing is to occur.
46     virtual bool CallbackMousePos(GLFWwindow* window, double x, double y) = 0;
47 };
48 
49 /// Manager for the OpenGL context and window.
50 class CH_OPENGL_API ChOpenGLWindow {
51   public:
52     /// Get the unique instance for the OpenGL window.
53     /// Call this function to get a pointer to the window.
getInstance()54     static ChOpenGLWindow& getInstance() {
55         static ChOpenGLWindow instance;
56         return instance;
57     }
58 
59     /// Initialize the window and set up the opengl viewer class.
60     void Initialize(int size_x,         ///< Width of window in pixels
61                     int size_y,         ///< Height of window in pixels
62                     const char* title,  ///< Window title string
63                     ChSystem* msystem   ///< The ChSystem that is attached to this window
64     );
65 
66     /// Attach a custom event receiver to the OpenGL window.
SetUserEventReceiver(ChOpenGLEventCB * receiver)67     void SetUserEventReceiver(ChOpenGLEventCB* receiver) { user_receivers.push_back(receiver); }
68 
69     /// This starts the drawing loop and takes control away from the main program.
70     /// This function is the easiest way to start rendering.
71     void StartDrawLoop(double time_step  ///< integration step size
72     );
73 
74     /// Perform a dynamics step, the user needs to use this so that pausing the simulation works correctly.
75     bool DoStepDynamics(double time_step  ///< integration step size
76     );
77 
78     /// Enable/disable HUD display (default: true).
EnableHUD(bool state)79     void EnableHUD(bool state) { render_hud = state; }
80 
81     /// Render the ChSystem and the HUD.
82     void Render();
83 
84     /// Check if the GLFW context is still valid and the window has not been closed.
85     bool Active();
86 
87     /// Check if the simulation is running or paused.
88     bool Running();
89 
90     /// Pause simulation.
91     void Pause();
92 
93     /// Set the camera position, look at and up vectors.
94     void SetCamera(ChVector<> pos,   ///< The position of the camera
95                    ChVector<> look,  ///< The point that the camera is looking at
96                    ChVector<> up,    ///< The up vector associated with the camera
97                    float scale = 0.5f,
98                    float near_clip_dist = 0.1f,
99                    float far_clip_dist = 1000.0f) {
100         viewer->render_camera.camera_position = glm::vec3(pos.x(), pos.y(), pos.z());
101         viewer->render_camera.camera_look_at = glm::vec3(look.x(), look.y(), look.z());
102         viewer->render_camera.camera_up = glm::vec3(up.x(), up.y(), up.z());
103         viewer->render_camera.camera_scale = scale;
104         viewer->render_camera.SetClipping(near_clip_dist, far_clip_dist);
105     }
106 
SetRenderMode(RenderMode mode)107     void SetRenderMode(RenderMode mode) { viewer->render_mode = mode; }
108 
109     /// Provides the version of the OpenGL context along with driver information.
110     static void GLFWGetVersion(GLFWwindow* main_window  ///< A pointer to the window/context
111     );
112 
113     // Callback wrapper for steps of the render loop. Works with Emscripten.
114     static void WrapRenderStep(void* stepFunction);
115 
116     // Pointer to the opengl viewer that handles rendering, text and user interaction
117     ChOpenGLViewer* viewer;
118 
119   private:
120     // Singleton constructor should be private so that a user cannot call it
ChOpenGLWindow()121     ChOpenGLWindow() : render_hud(true) {}
122 
123     // Singleton destructor should be private so that a user cannot call it
~ChOpenGLWindow()124     ~ChOpenGLWindow() {}
125 
126     ChOpenGLWindow(ChOpenGLWindow const&);  // Don't Implement.
127     void operator=(ChOpenGLWindow const&);  // Don't implement
128 
129     // GLFW error callback, returns error string
130     static void CallbackError(int error, const char* description);
131 
132     // GLFW close callback, called when window is closed
133     static void CallbackClose(GLFWwindow* window);
134 
135     // GLFW reshape callback, handles window resizing events
136     static void CallbackReshape(GLFWwindow* window, int w, int h);
137 
138     // GLFW keyboard callback, handles keyboard events
139     static void CallbackKeyboard(GLFWwindow* window, int key, int scancode, int action, int mode);
140 
141     // GLFW mouse button callback, handles mouse button events
142     static void CallbackMouseButton(GLFWwindow* window, int button, int action, int mods);
143 
144     // GLFW mouse position callback, handles events generated by changes in
145     // mouse position
146     static void CallbackMousePos(GLFWwindow* window, double x, double y);
147 
148     // Pointer to the opengl context
149     GLFWwindow* window;
150     int poll_frame;
151     bool render_hud;
152     std::vector<ChOpenGLEventCB*> user_receivers;
153 };
154 
155 /// @} opengl_module
156 
157 }  // namespace opengl
158 }  // namespace chrono
159 
160 #endif
161