OpenFrames
WindowProxy.hpp
Go to the documentation of this file.
1 /***********************************
2  Copyright 2018 Ravishankar Mathur
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15  ***********************************/
16 
21 #ifndef _OF_WINDOWPROXY_
22 #define _OF_WINDOWPROXY_
23 
24 #include <OpenFrames/Export.h>
28 #include <OpenThreads/Thread>
29 #include <osg/FrameStamp>
30 #include <osg/Timer>
31 #include <osg/Referenced>
32 #include <osg/observer_ptr>
33 #include <osg/ref_ptr>
34 #include <osgViewer/CompositeViewer>
35 #include <osgViewer/GraphicsWindow>
36 #include <vector>
37 #include <set>
38 
39 // Define shortcuts for callback function signatures
40 #define BASIC_CALLBACK_SIG unsigned int *winID, unsigned int *row, unsigned int *col
41 #define KEYPRESS_SIG BASIC_CALLBACK_SIG, int *key
42 #define MOUSEMOTION_SIG BASIC_CALLBACK_SIG, float *x, float *y
43 #define BUTTON_SIG MOUSEMOTION_SIG, unsigned int *button
44 #define VR_SIG BASIC_CALLBACK_SIG, const OpenVREvent *vrEvent
45 
46 namespace OpenFrames
47 {
48  class FrameManager;
49  class WindowProxy;
50 
59  class EmbeddedGraphics : public osgViewer::GraphicsWindow
60  {
61  public:
62  EmbeddedGraphics(int x, int y, int width, int height, WindowProxy *window);
63 
64  virtual bool isSameKindAs(const Object* object) const { return dynamic_cast<const EmbeddedGraphics*>(object)!=0; }
65  virtual const char* libraryName() const { return "OpenFrames"; }
66  virtual const char* className() const { return "EmbeddedGraphics"; }
67 
70  virtual void setWindowName(const std::string& name) { _traits->windowName = name; }
71 
73  virtual bool makeCurrentImplementation();
74  virtual void swapBuffersImplementation();
75 
77  void setMakeCurrentFunction(void (*fcn)(unsigned int *winID, bool *success));
78 
81  void setUpdateContextFunction(void (*fcn)(unsigned int *winID, bool *success));
82  bool updateContextImplementation();
83 
85  void setSwapBuffersFunction(void (*fcn)(unsigned int *winID));
86 
88  virtual bool realizeImplementation();
89  virtual bool isRealizedImplementation() const { return _realized; }
90 
92  virtual bool valid() const { return true; }
93  virtual bool releaseContextImplementation() { return true; }
94  virtual void closeImplementation() {}
95  virtual void grabFocus() {}
96  virtual void grabFocusIfPointerInWindow() {}
97  virtual void raiseWindow() {}
98 
99  protected:
100  virtual ~EmbeddedGraphics();
101 
103  void (*_makeCurrent)(unsigned int *winID, bool *success);
104  void (*_updateContext)(unsigned int *winID, bool *success);
105  void (*_swapBuffers)(unsigned int *winID);
106 
107  WindowProxy *_window; // Pointer to the WindowProxy that represents the window
108  bool _realized; // Whether this context has been realized
109  };
110 
117  class OF_EXPORT WindowEventHandler : public osgGA::GUIEventHandler
118  {
119  public:
121 
122  // Event handler function
123  bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
124 
125  // Indicate that the associated WindowProxy has been modified in some way
126  void windowModified();
127 
128  // Set the callback functions for various events. These will be called when the corresponding
129  // event occurs (ie user presses a key, moves the mouse, etc...).
130  void setKeyPressCallback(void (*fcn)(KEYPRESS_SIG)) // Keyboard key press callback
131  { _keyPressCallback = fcn; }
132 
133  void setMouseMotionCallback(void (*fcn)(MOUSEMOTION_SIG)) // Mouse moved callback
134  { _mouseMotionCallback = fcn; }
135 
136  void setButtonPressCallback(void (*fcn)(BUTTON_SIG)) // Mouse button pressed callback
137  { _buttonPressCallback = fcn; }
138 
139  void setButtonReleaseCallback(void (*fcn)(BUTTON_SIG)) // Mouse button released callback
140  { _buttonReleaseCallback = fcn; }
141 
142  void setVREventCallback(void (*fcn)(VR_SIG)) // VR controller event callback
143  { _vrEventCallback = fcn; }
144 
145  protected:
146  virtual ~WindowEventHandler();
147 
148  void getRenderRectangle(float x, float y, unsigned int &row, unsigned int &col);
149  void selectRenderRectangle(unsigned int row, unsigned int col);
150 
151  WindowProxy *_window;
152  unsigned int _currentRow, _currentCol;
153 
154  void (*_keyPressCallback)(KEYPRESS_SIG);
155  void (*_mouseMotionCallback)(MOUSEMOTION_SIG);
156  void (*_buttonPressCallback)(BUTTON_SIG);
157  void (*_buttonReleaseCallback)(BUTTON_SIG);
158  void (*_vrEventCallback)(VR_SIG);
159  };
160 
172  class OF_EXPORT WindowProxy : public OpenThreads::Thread, public osg::Referenced
173  {
174  public:
175  // A list of RenderRectangles for each grid position
176  typedef std::vector<osg::ref_ptr<RenderRectangle> > RenderList;
177 
178  WindowProxy(int x, int y,
179  unsigned int width, unsigned int height,
180  unsigned int nrow, unsigned int ncol,
181  bool embedded = false, bool useVR = false);
182 
183  virtual void cancelCleanup();
184 
188  void setWindowName(const std::string& name);
189 
190  unsigned int getWindowWidth() const;
191  unsigned int getWindowHeight() const;
192 
193  bool isEmbedded() const { return _isEmbedded; }
194 
200  void keyPress(int key);
201  void keyRelease(int key);
202  void mouseMotion(float x, float y);
203  void buttonPress(float x, float y, unsigned int button);
204  void buttonRelease(float x, float y, unsigned int button);
205  void resizeWindow(int x, int y, unsigned int width, unsigned int height);
206 
208  void setupGrid(unsigned int width, unsigned int height);
209 
211  void shutdown() { _viewer->setDone(true); }
212 
214  void setTime(double time);
215  double getTime() const
216  {
217  if(_timeSyncWinProxy.valid()) return _timeSyncWinProxy->getTime();
218  else return _currTime;
219  }
220 
222  void setTimeRange(double tMin, double tMax);
223  void getTimeRange(double& tMin, double& tMax) const;
224 
225  void pauseTime(bool pause);
226  bool isTimePaused() const
227  {
228  if(_timeSyncWinProxy.valid()) return _timeSyncWinProxy->isTimePaused();
229  else return _timePaused;
230  }
231 
232  void setTimeScale(double tscale);
233  double getTimeScale() const
234  {
235  if(_timeSyncWinProxy.valid()) return _timeSyncWinProxy->getTimeScale();
236  else return _timeScale;
237  }
238 
247  bool synchronizeTime(WindowProxy *winproxy);
248  WindowProxy* getTimeSyncWindow() const { return _timeSyncWinProxy.get(); }
249 
252  {
253  IDLE = 0, // Waiting to initiate animation
254  INITIALIZING, // Initializing animation
255  ANIMATING, // Inside animation loop, and actively rendering
256  PAUSED, // Inside animation loop, but rendering is paused
257  FAILED, // Error during initialization
258  SUCCESS // Successfully finished animating
259  };
260 
266  void pauseAnimation(bool pause);
267 
269  AnimationState getAnimationState() const { return _animationState; }
270 
272  bool isAnimating() const { return ((_animationState == ANIMATING) || (_animationState == PAUSED)); }
273 
275  bool doneAnimating() const { return ((_animationState == FAILED) || (_animationState == SUCCESS)); }
276 
278  void resetAnimationState() { if(doneAnimating()) _animationState = IDLE; }
279 
281  inline void setDesiredFramerate(const double &fps)
282  { _frameThrottle.setDesiredFramerate(fps); }
283 
285  inline double getDesiredFramerate()
286  { return _frameThrottle.getDesiredFramerate(); }
287 
289  inline double getFramerate()
290  { return _frameThrottle.getFramerate(); }
291 
292  osgViewer::CompositeViewer* getViewer() const { return _viewer.get(); }
293 
295  void setGridSize(unsigned int row, unsigned int col);
296  inline unsigned int getNumRows() const { return _nRow; }
297  inline unsigned int getNumCols() const { return _nCol; }
298 
299  void setScene(FrameManager *fm, unsigned int row, unsigned int col);
300  FrameManager* getScene(unsigned int row, unsigned int col);
301 
303  RenderRectangle* getGridPosition(unsigned int row, unsigned int col);
304 
306  void setMakeCurrentFunction(void (*fcn)(unsigned int *winID, bool *success));
307 
311  void setUpdateContextFunction(void (*fcn)(unsigned int *winID, bool *success));
312 
314  void setSwapBuffersFunction(void (*fcn)(unsigned int *winID));
315 
318  { _eventHandler->setKeyPressCallback(fcn); }
319 
320  void setMouseMotionCallback(void (*fcn)(MOUSEMOTION_SIG))
321  { _eventHandler->setMouseMotionCallback(fcn); }
322 
323  void setButtonPressCallback(void (*fcn)(BUTTON_SIG))
324  { _eventHandler->setButtonPressCallback(fcn); }
325 
326  void setButtonReleaseCallback(void (*fcn)(BUTTON_SIG))
327  { _eventHandler->setButtonReleaseCallback(fcn); }
328 
329  void setVREventCallback(void (*fcn)(VR_SIG))
330  { _eventHandler->setVREventCallback(fcn); }
331 
334  inline void setID(unsigned int id) { _winID = id; }
335  inline unsigned int getID() const { return _winID; }
336 
338  bool getUseVR() { return _useVR; }
339 
341  const OpenVRDevice* getOpenVRDevice() const { return _ovrDevice; }
342 
344  void setWorldUnitsPerMeter(double worldUnitsPerMeter)
345  {
346  if (_useVR) _ovrDevice->setWorldUnitsPerMeter(worldUnitsPerMeter);
347  }
348  double getWorldUnitsPerMeter()
349  {
350  if (_useVR) return _ovrDevice->getWorldUnitsPerMeter();
351  else return 1.0; // Unused if VR is disabled
352  }
353 
355  void setWorldUnitsPerMeterLimits(const double& minWorldUnitsPerMeter, const double& maxWorldUnitsPerMeter)
356  {
357  if (_useVR) _ovrDevice->setWorldUnitsPerMeterLimits(minWorldUnitsPerMeter, maxWorldUnitsPerMeter);
358  }
359  void getWorldUnitsPerMeterLimits(double &minWorldUnitsPerMeter, double &maxWorldUnitsPerMeter)
360  {
361  if (_useVR) _ovrDevice->getWorldUnitsPerMeterLimits(minWorldUnitsPerMeter, maxWorldUnitsPerMeter);
362  }
363 
365  void setUserHeight(const double &height)
366  {
367  if (_useVR) _ovrDevice->setUserHeight(height);
368  }
369 
371  virtual void run();
372 
374  void printInfo();
375 
377  void captureWindow();
378 
382  void setWindowCaptureFile(const std::string& fname, const std::string& fext);
383 
386  void setWindowCaptureKey(int key)
387  { _screenCaptureHandler->setKeyEventTakeScreenShot(key); }
388 
389  protected:
390  virtual ~WindowProxy();
391 
392  bool setupWindow();
393  void collectScenes();
394  void frame();
395 
398  unsigned int _winID;
399 
400  unsigned int _nRow, _nCol; // Number of rows/columns in this window's grid
401 
402  bool _isEmbedded; // True if the user wants to provide their own OpenGL window
403 
404  RenderList _renderList; // List of subwindows to be rendered
405 
406  typedef std::set<FrameManager*> SceneSet;
407  SceneSet _scenes; // Set of all unique scenes
408 
410  osg::ref_ptr<osgViewer::CompositeViewer> _viewer;
411 
413  osg::ref_ptr<osgViewer::GraphicsWindow> _window;
414 
416  osg::ref_ptr<EmbeddedGraphics> _embeddedGraphics;
417 
419  osg::ref_ptr<WindowEventHandler> _eventHandler;
420 
422  osg::ref_ptr<osgViewer::StatsHandler> _statsHandler;
423 
425  osg::ref_ptr<osgViewer::ScreenCaptureHandler> _screenCaptureHandler;
426 
427  FramerateLimiter _frameThrottle; // Controls animation framerate
428 
430  AnimationState _animationState; // Current animation state
431  bool _pauseAnimation; // Indicate that animation should be paused
432  bool _timePaused;
433  osg::Timer_t _Tref;
434  double _currTime, _offsetTime, _timeScale;
435  double _minTime, _maxTime;
436  osg::observer_ptr<WindowProxy> _timeSyncWinProxy;
437 
438  bool _useVR; // Whether to use VR rendering
439  osg::ref_ptr<OpenVRDevice> _ovrDevice; // OpenVR interface
440  osg::ref_ptr<VRTextureBuffer> _vrTextureBuffer; // VR texture buffers
441  };
442 
443 }
444 
445 #endif
osg::ref_ptr< WindowEventHandler > _eventHandler
Definition: WindowProxy.hpp:419
void setDesiredFramerate(const double &fps)
Definition: WindowProxy.hpp:281
void setWindowCaptureKey(int key)
Definition: WindowProxy.hpp:386
This class implements a framerate-limiting algorithm.
Definition: FramerateLimiter.hpp:40
Represents data needed to use an OpenVR-supported HMD.
Definition: OpenVRDevice.hpp:87
void shutdown()
Definition: WindowProxy.hpp:211
void resetAnimationState()
If animation is done, then reset the animation state.
Definition: WindowProxy.hpp:278
const OpenVRDevice * getOpenVRDevice() const
Definition: WindowProxy.hpp:341
virtual bool makeCurrentImplementation()
virtual bool realizeImplementation()
void setUpdateContextFunction(void(*fcn)(unsigned int *winID, bool *success))
osg::ref_ptr< osgViewer::GraphicsWindow > _window
Definition: WindowProxy.hpp:413
osg::ref_ptr< osgViewer::ScreenCaptureHandler > _screenCaptureHandler
Definition: WindowProxy.hpp:425
void setMakeCurrentFunction(void(*fcn)(unsigned int *winID, bool *success))
unsigned int _winID
Definition: WindowProxy.hpp:398
void setWorldUnitsPerMeter(double worldUnitsPerMeter)
Definition: WindowProxy.hpp:344
AnimationState _animationState
Definition: WindowProxy.hpp:430
Defines an interface that can draw a scene onto any window.
Definition: WindowProxy.hpp:172
Definition: CoordinateAxes.hpp:29
virtual bool valid() const
Definition: WindowProxy.hpp:92
void setUserHeight(const double &height)
Definition: WindowProxy.hpp:365
#define KEYPRESS_SIG
Definition: OF_Interface.h:53
This class handles incoming events.
Definition: WindowProxy.hpp:117
void(* _makeCurrent)(unsigned int *winID, bool *success)
Definition: WindowProxy.hpp:103
AnimationState
Definition: WindowProxy.hpp:251
AnimationState getAnimationState() const
Get the current animation state.
Definition: WindowProxy.hpp:269
void setID(unsigned int id)
Definition: WindowProxy.hpp:334
void setSwapBuffersFunction(void(*fcn)(unsigned int *winID))
osg::ref_ptr< EmbeddedGraphics > _embeddedGraphics
Definition: WindowProxy.hpp:416
double getFramerate()
Definition: WindowProxy.hpp:289
virtual void setWindowName(const std::string &name)
Definition: WindowProxy.hpp:70
#define BUTTON_SIG
Definition: OF_Interface.h:57
double getDesiredFramerate()
Definition: WindowProxy.hpp:285
osg::ref_ptr< osgViewer::StatsHandler > _statsHandler
Definition: WindowProxy.hpp:422
The class of GraphicsWindow used for embedded graphics.
Definition: WindowProxy.hpp:59
void setWorldUnitsPerMeterLimits(const double &minWorldUnitsPerMeter, const double &maxWorldUnitsPerMeter)
Definition: WindowProxy.hpp:355
#define MOUSEMOTION_SIG
Definition: OF_Interface.h:55
osg::ref_ptr< osgViewer::CompositeViewer > _viewer
Definition: WindowProxy.hpp:410
bool isAnimating() const
Determine whether WindowProxy is in its animation loop.
Definition: WindowProxy.hpp:272
void setKeyPressCallback(void(*fcn)(KEYPRESS_SIG))
Definition: WindowProxy.hpp:317
bool doneAnimating() const
Determine whether WindowProxy is done animating.
Definition: WindowProxy.hpp:275
bool getUseVR()
Definition: WindowProxy.hpp:338