SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
ImGuiWrapper.h
Go to the documentation of this file.
1 /**
2  * \file ImGuiWrapper.cpp
3  * \brief Wrapper Class around the external ImGui GUI-framework
4 // See also: https://github.com/ocornut/imgui
5  * \date October 2015
6  * \authors Marcus Hudritsch
7  * \copyright http://opensource.org/licenses/GPL-3.0
8  * \remarks Please use clangformat to format the code. See more code style on
9  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
10 */
11 
12 #ifndef IMGUIWRAPPER_H
13 #define IMGUIWRAPPER_H
14 
15 #include <imgui.h>
16 #include <SL.h>
17 #include <SLEnums.h>
18 #include <SLVec2.h>
19 #include <math/SLRect.h>
20 #include <SLUiInterface.h>
21 #include <HighResTimer.h>
22 
23 class SLScene;
24 class SLSceneView;
25 struct ImGuiContext;
26 
27 /*! ImGuiRenderer is used by ImGuiWrapper to render a custom. We need this interface, as there may
28 be different renderers (e.g. ImGuiRendererOpenGL) and because we want to share a common ImGuiContext
29 over multiple ImGuiWrapper instances.
30 */
32 {
33 public:
34  ImGuiRenderer(ImGuiContext* context)
35  : _context(context)
36  {
37  assert(context);
38  }
39  virtual ~ImGuiRenderer() {}
40  virtual void render(const SLRecti& viewportRect) {}
41 
42 protected:
43  ImGuiContext* _context;
44 };
45 
46 // Wraps opengl code for drawing imgui with opengl. We use the same
47 // Fonts have to be defined first, because they are needed to generate the font
48 // texture in the correct size.
49 //
51 {
52 public:
53  ImGuiRendererOpenGL(ImGuiContext* context)
54  : ImGuiRenderer(context)
55  {
56  // Attention: define your fonts before calling this function!
58  }
59 
61  {
63  }
64 
65  void render(const SLRecti& viewportRect) override;
66 
67 private:
68  void printCompileErrors(SLint shaderHandle, const SLchar* src);
69  void createOpenGLObjects();
70  void deleteOpenGLObjects();
71 
72  unsigned int _fontTexture{0}; //!< OpenGL texture id for font
73  int _progHandle{0}; //!< OpenGL handle for shader program
74  int _vertHandle{0}; //!< OpenGL handle for vertex shader
75  int _fragHandle{0}; //!< OpenGL handle for fragment shader
76  int _attribLocTex{0}; //!< OpenGL attribute location for texture
77  int _attribLocProjMtx{0}; //!< OpenGL attribute location for ???
78  int _attribLocPosition{0}; //!< OpenGL attribute location for vertex pos.
79  int _attribLocUV{0}; //!< OpenGL attribute location for texture coords
80  int _attribLocColor{0}; //!< OpenGL attribute location for color
81  unsigned int _vboHandle{0}; //!< OpenGL handle for vertex buffer object
82  unsigned int _vaoHandle{0}; //!< OpenGL vertex array object handle
83  unsigned int _elementsHandle{0}; //!< OpenGL handle for vertex indexes
84 };
85 
86 /*! Wraps the following things:
87 - Create ImGuiContext (which is shared over all instances of ImGuiWrapper)
88 - Destroy ImGuiContext
89 - Init general imgui stuff (e.g. define where to store ini file)
90 - Load fonts (these are shared over the all ImGuiWrappers)
91 - Instantiate renderer
92 */
94 {
95 public:
96  ImGuiEngine(std::string configDir, ImFontAtlas* fontAtlas)
97  {
98  _context = ImGui::CreateContext(fontAtlas);
99  init(configDir);
100 
101  // make sure fonts are loaded before texture for fonts is generated
102  //(here fonts are transferred with font atlas)
104  assert(_renderer);
105  }
106 
108  {
109  if (_renderer)
110  delete _renderer;
111  ImGui::DestroyContext(_context);
112  _context = nullptr;
113  }
114 
115  ImGuiRenderer* renderer() const { return _renderer; }
116  ImGuiContext* context() const { return _context; }
117 
118 private:
119  void init(const std::string& configPath);
120 
122  ImGuiContext* _context{nullptr};
123  std::string _iniFilename;
124 };
125 
126 // e.g. scrolling of child window by touch down and move.
127 // We need the possibility to turn it off because it conflicts with drag and drop of windows
128 // if a window is not fixed.
130 {
131 public:
132  void enable()
133  {
134  _enabled = true;
135  _lastPosY = 0.f;
136  _diff = 0.f;
137  _vMW = 0.f;
138  _tOld = 0.f;
139  }
140 
141  void disable()
142  {
143  _enabled = false;
144  }
145 
146  // call on mouse move
147  void moveTo(const float yPos)
148  {
149  _diff -= (_lastPosY - yPos);
150  _lastPosY = yPos;
151  }
152 
153  // call on mouse down
154  void start(const float yPos)
155  {
156  _lastPosY = yPos;
157  _diff = 0.f;
158  _vMW = 0.f;
159  _tOld = 0.f;
160  }
161 
162  // call to updateRec mouse wheel in render function
163  // As we are using the io.mouseWheel from imgui to set the window position,
164  // we have to convert to mouseWheel coordinates.
165  float getScrollInMouseWheelCoords(const bool mouseDown, const float fontSize, const float t)
166  {
167  float dt = t - _tOld;
168  _tOld = t;
169 
170  if (mouseDown)
171  {
172  // Convertion to mouse wheel coords: One mouse wheel unit scrolls about 5 lines of text
173  //(see io.MouseWheel comment)
174  float diffMW = _diff / (fontSize * 5.f);
175  _diff = 0; // diff consumed, reset it
176 
177  // calculate v (of mouse wheel), we need it when left mouse button goes up
178  if (dt > 0.000001f)
179  {
180  // v = s / t
181  _vMW = diffMW / dt;
182  }
183 
184  return diffMW;
185  }
186  else if (std::abs(_vMW) > 0.000001f)
187  {
188  // velocity damping
189  // v = v - a * t
190  if (_vMW > 0)
191  {
192  _vMW = _vMW - _aMW * dt;
193  if (_vMW < 0.f)
194  _vMW = 0.f;
195  }
196  else
197  {
198  _vMW = _vMW + _aMW * dt;
199  if (_vMW > 0.f)
200  _vMW = 0.f;
201  }
202 
203  // s = v * t
204  return _vMW * dt;
205  }
206  else
207  return 0.f;
208  }
209 
210  bool enabled() const { return _enabled; }
211 
212 private:
213  bool _enabled = false;
214  float _lastPosY = 0.f; //!< mouse down start position
215  float _diff = 0.f; //!< Summed up y difference between mouse move events
216  float _vMW = 0.f; //!< Mouse wheel velocity: used after pan scrolling for additional scrolling
217  float _tOld = 0.f; //!< Time at last call to getScrollInMouseWheelCoords
218  const float _aMW = 20.0f; //!< Mouse wheel acceleration (subtended velocity direction)
219 };
220 
221 //-----------------------------------------------------------------------------
222 //! ImGui Interface class for forwarding all events to the ImGui Handlers
223 /*! ImGui is a super easy GUI library for the rendering of a UI with OpenGL.
224 For more information see: https://github.com/ocornut/imgui\n
225 \n
226 This class provides only the interface into ImGui. In the event handlers of
227 SLSceneView the according callback in ImGui is called.\n
228 There is no UI drawn with this class. It must be defined in another class
229 that provides the build function. For the Demo apps this is done in the class
230 SLDemoGui and the build function is passed e.g. in glfwMain function of the
231 app-demo project.\n
232 \n
233 The full call stack for rendering one frame is:\n
234 - The top-level onPaint of the app (Win, Linux, MacOS, Android or iOS)
235  - slUpdateAndPaint: C-Interface function of SLProject
236  - SLSceneView::onPaint: Main onPaint function of a sceneview
237  - SLImGui::newFrame: Initializes a new GUI frame
238  - ImGui::NewFrame()
239  - SLImGui::build: The UI build function
240  - ... normal scene rendering of SLProject
241  - SLSceneView::draw2DGL:
242  - ImGui::Render
243  - SLImGui::render(ImGui::GetDrawData())
244  - SLDemoGui::buildDemoGui: Builds the full UI
245 */
246 
247 //! ImGuiWrapper implements SLUiInterface for ImGui.
248 /*! The interface function are called by a SLSceneView instance
249  */
251 {
252 public:
253  ImGuiWrapper(ImGuiContext* context, ImGuiRenderer* renderer);
254  ~ImGuiWrapper() override;
255  void init(const std::string& configPath) override;
256 
257  void onInitNewFrame(SLScene* s, SLSceneView* sv) override;
258  void onResize(SLint scrW, SLint scrH) override;
259  void onPaint(const SLRecti& viewport) override;
260  void onMouseDown(SLMouseButton button, SLint x, SLint y) override;
261  void onMouseUp(SLMouseButton button, SLint x, SLint y) override;
262  // returns true if it wants to capture mouse
263  void onMouseMove(SLint xPos, SLint yPos) override;
264  void onMouseWheel(SLfloat yoffset) override;
265  void onKeyPress(SLKey key, SLKey mod) override;
266  void onKeyRelease(SLKey key, SLKey mod) override;
267  void onCharInput(SLuint c) override;
268  void onClose() override;
270  bool doNotDispatchKeyboard() override;
271  bool doNotDispatchMouse() override;
272 
273  // Overwrite this function to implement your imgui visualization
274  virtual void build(SLScene* s, SLSceneView* sv) = 0;
275 
276 protected:
278  ImGuiContext* _context{nullptr};
279 
280 private:
281  SLfloat _timeSec; //!< Time in seconds
282  SLfloat _mouseWheel{0}; //!< Mouse wheel position
283 
285 };
286 //-----------------------------------------------------------------------------
287 #endif
static SLint mouseX
Last mouse position x in pixels.
static SLint mouseY
Last mouse position y in pixels.
float SLfloat
Definition: SL.h:173
unsigned int SLuint
Definition: SL.h:171
char SLchar
Definition: SL.h:162
int SLint
Definition: SL.h:170
SLMouseButton
Mouse button codes.
Definition: SLEnums.h:98
SLKey
Keyboard key codes enumeration.
Definition: SLEnums.h:16
ImGuiContext * _context
Definition: ImGuiWrapper.h:122
ImGuiContext * context() const
Definition: ImGuiWrapper.h:116
void init(const std::string &configPath)
ImGuiRenderer * _renderer
Definition: ImGuiWrapper.h:121
ImGuiEngine(std::string configDir, ImFontAtlas *fontAtlas)
Definition: ImGuiWrapper.h:96
ImGuiRenderer * renderer() const
Definition: ImGuiWrapper.h:115
std::string _iniFilename
Definition: ImGuiWrapper.h:123
ImGuiRenderer(ImGuiContext *context)
Definition: ImGuiWrapper.h:34
virtual void render(const SLRecti &viewportRect)
Definition: ImGuiWrapper.h:40
virtual ~ImGuiRenderer()
Definition: ImGuiWrapper.h:39
ImGuiContext * _context
Definition: ImGuiWrapper.h:43
int _fragHandle
OpenGL handle for fragment shader.
Definition: ImGuiWrapper.h:75
int _attribLocPosition
OpenGL attribute location for vertex pos.
Definition: ImGuiWrapper.h:78
void printCompileErrors(SLint shaderHandle, const SLchar *src)
Prints the compile errors in case of a GLSL compile failure.
int _vertHandle
OpenGL handle for vertex shader.
Definition: ImGuiWrapper.h:74
int _attribLocColor
OpenGL attribute location for color.
Definition: ImGuiWrapper.h:80
int _attribLocUV
OpenGL attribute location for texture coords.
Definition: ImGuiWrapper.h:79
int _attribLocTex
OpenGL attribute location for texture.
Definition: ImGuiWrapper.h:76
unsigned int _elementsHandle
OpenGL handle for vertex indexes.
Definition: ImGuiWrapper.h:83
int _attribLocProjMtx
OpenGL attribute location for ???
Definition: ImGuiWrapper.h:77
unsigned int _fontTexture
OpenGL texture id for font.
Definition: ImGuiWrapper.h:72
ImGuiRendererOpenGL(ImGuiContext *context)
Definition: ImGuiWrapper.h:53
void deleteOpenGLObjects()
Deletes all OpenGL objects for drawing the imGui.
int _progHandle
OpenGL handle for shader program.
Definition: ImGuiWrapper.h:73
unsigned int _vboHandle
OpenGL handle for vertex buffer object.
Definition: ImGuiWrapper.h:81
void render(const SLRecti &viewportRect) override
void createOpenGLObjects()
Creates all OpenGL objects for drawing the imGui.
unsigned int _vaoHandle
OpenGL vertex array object handle.
Definition: ImGuiWrapper.h:82
ImGui Interface class for forwarding all events to the ImGui Handlers.
Definition: ImGuiWrapper.h:251
void onMouseDown(SLMouseButton button, SLint x, SLint y) override
Callback on mouse button down event.
ImGuiWrapper(ImGuiContext *context, ImGuiRenderer *renderer)
virtual void build(SLScene *s, SLSceneView *sv)=0
PanScrolling _panScroll
Definition: ImGuiWrapper.h:277
void init(const std::string &configPath) override
Initializes OpenGL handles to zero and sets the ImGui key map.
void onMouseWheel(SLfloat yoffset) override
Callback for the mouse scroll movement.
ImGuiContext * _context
Definition: ImGuiWrapper.h:278
void onMouseUp(SLMouseButton button, SLint x, SLint y) override
Callback on mouse button up event.
void onKeyPress(SLKey key, SLKey mod) override
Callback on key press event.
~ImGuiWrapper() override
void onResize(SLint scrW, SLint scrH) override
Callback if window got resized.
void onClose() override
Callback on closing the application.
void onMouseMove(SLint xPos, SLint yPos) override
Updates the mouse cursor position.
SLfloat _timeSec
Time in seconds.
Definition: ImGuiWrapper.h:281
bool doNotDispatchKeyboard() override
inform if user keyboard input was consumed by the ui
SLfloat _mouseWheel
Mouse wheel position.
Definition: ImGuiWrapper.h:282
void onPaint(const SLRecti &viewport) override
Callback for main rendering for the ImGui GUI system.
void onInitNewFrame(SLScene *s, SLSceneView *sv) override
Inits a new frame for the ImGui system.
void onCharInput(SLuint c) override
Callback on character input.
void renderExtraFrame(SLScene *s, SLSceneView *sv, SLint mouseX, SLint mouseY) override
Renders an extra frame with the current mouse position.
ImGuiRenderer * _renderer
Definition: ImGuiWrapper.h:284
void onKeyRelease(SLKey key, SLKey mod) override
Callback on key release event.
bool doNotDispatchMouse() override
inform if user mouse input was consumed by the ui
void start(const float yPos)
Definition: ImGuiWrapper.h:154
void moveTo(const float yPos)
Definition: ImGuiWrapper.h:147
bool enabled() const
Definition: ImGuiWrapper.h:210
float _vMW
Mouse wheel velocity: used after pan scrolling for additional scrolling.
Definition: ImGuiWrapper.h:216
float _diff
Summed up y difference between mouse move events.
Definition: ImGuiWrapper.h:215
float getScrollInMouseWheelCoords(const bool mouseDown, const float fontSize, const float t)
Definition: ImGuiWrapper.h:165
float _tOld
Time at last call to getScrollInMouseWheelCoords.
Definition: ImGuiWrapper.h:217
const float _aMW
Mouse wheel acceleration (subtended velocity direction)
Definition: ImGuiWrapper.h:218
void disable()
Definition: ImGuiWrapper.h:141
float _lastPosY
mouse down start position
Definition: ImGuiWrapper.h:214
The SLScene class represents the top level instance holding the scene structure.
Definition: SLScene.h:47
SceneView class represents a dynamic real time 3D view onto the scene.
Definition: SLSceneView.h:69
Interface for ui integration in SLSceneView.
Definition: SLUiInterface.h:24
T abs(T a)
Definition: Utils.h:249
T mod(T a, T b)
Definition: Utils.h:250