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