GraphicsWindow 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. #ifndef OSGVIEWER_GRAPHICWINDOW
  14. #define OSGVIEWER_GRAPHICWINDOW 1
  15. #include <osg/GraphicsContext>
  16. #include <osg/Notify>
  17. #include <osgGA/EventQueue>
  18. #include <osgGA/GUIActionAdapter>
  19. #include <osgViewer/Export>
  20. extern "C"
  21. {
  22. typedef void (* CGraphicsWindowFunction) (void);
  23. }
  24. namespace osgViewer {
  25. class View;
  26. /** Base class for providing Windowing API agnostic access to creating and managing graphics window and events.
  27. * Note, the GraphicsWindow is subclassed from osg::GraphicsContext, and to provide an implementation you'll need to implement its
  28. * range of pure virtual functions, you'll find these all have naming convention methodNameImplementation(..).
  29. * GraphicsWindow adds the event queue on top of the GraphicsContext, thereby adding a mechanism for adapting Windowing events
  30. * as well as basics graphics context work, you should wire up custom GraphicsWindowImplementation to push their events through
  31. * into the EventQueue. */
  32. class OSGVIEWER_EXPORT GraphicsWindow : public osg::GraphicsContext, public osgGA::GUIActionAdapter
  33. {
  34. public:
  35. GraphicsWindow() { _eventQueue = new osgGA::EventQueue; _eventQueue->setGraphicsContext(this); }
  36. virtual bool isSameKindAs(const Object* object) const { return dynamic_cast<const GraphicsWindow*>(object)!=0; }
  37. virtual const char* libraryName() const { return "osgViewer"; }
  38. virtual const char* className() const { return "GraphicsWindow"; }
  39. void setEventQueue(osgGA::EventQueue* eventQueue) { _eventQueue = eventQueue; }
  40. osgGA::EventQueue* getEventQueue() { return _eventQueue.get(); }
  41. const osgGA::EventQueue* getEventQueue() const { return _eventQueue.get(); }
  42. /** Check events, return true if events have been received.*/
  43. virtual bool checkEvents() { return !(_eventQueue->empty()); }
  44. /** Set the window's position and size.*/
  45. void setWindowRectangle(int x, int y, int width, int height)
  46. {
  47. if (setWindowRectangleImplementation(x ,y ,width, height) && _traits.valid())
  48. {
  49. resized(x,y,width,height);
  50. }
  51. }
  52. /** implementation of setWindowRectangle, should be implemented by derived classes */
  53. virtual bool setWindowRectangleImplementation(int /*x*/, int /*y*/, int /*width*/, int /*height*/) { osg::notify(osg::NOTICE)<<"GraphicsWindow::setWindowRectangleImplementation(..) not implemented."<<std::endl; return false; }
  54. /** Get the window's position and size.*/
  55. virtual void getWindowRectangle(int& x, int& y, int& width, int& height) { if (_traits.valid()) { x = _traits->x; y = _traits->y; width = _traits->width; height = _traits->height; } }
  56. /** Set Window decoration.*/
  57. void setWindowDecoration(bool flag)
  58. {
  59. if (setWindowDecorationImplementation(flag) && _traits.valid())
  60. {
  61. _traits->windowDecoration = flag;
  62. }
  63. }
  64. /** implementation of setWindowDecoration, should be implemented by derived classes */
  65. virtual bool setWindowDecorationImplementation(bool /*flag*/) { osg::notify(osg::NOTICE)<<"GraphicsWindow::setWindowDecorationImplementation(..) not implemented."<<std::endl; return false; }
  66. /** Set Window decoration.*/
  67. virtual bool getWindowDecoration() const { return _traits.valid() ? _traits->windowDecoration : false; }
  68. /** Get focus.*/
  69. virtual void grabFocus() { osg::notify(osg::NOTICE)<<"GraphicsWindow::grabFocus(..) not implemented."<<std::endl; }
  70. /** Get focus on if the pointer is in this window.*/
  71. virtual void grabFocusIfPointerInWindow() { osg::notify(osg::NOTICE)<<"GraphicsWindow::grabFocusIfPointerInWindow(..) not implemented."<<std::endl; }
  72. /** Raise the window to the top.*/
  73. virtual void raiseWindow() { osg::notify(osg::NOTICE)<<"GraphicsWindow::raiseWindow(..) not implemented."<<std::endl; }
  74. /** Mouse cursor types, the same ones already present with ancient glut ... */
  75. enum MouseCursor {
  76. InheritCursor,
  77. NoCursor,
  78. RightArrowCursor,
  79. LeftArrowCursor,
  80. InfoCursor,
  81. DestroyCursor,
  82. HelpCursor,
  83. CycleCursor,
  84. SprayCursor,
  85. WaitCursor,
  86. TextCursor,
  87. CrosshairCursor,
  88. HandCursor,
  89. UpDownCursor,
  90. LeftRightCursor,
  91. TopSideCursor,
  92. BottomSideCursor,
  93. LeftSideCursor,
  94. RightSideCursor,
  95. TopLeftCorner,
  96. TopRightCorner,
  97. BottomRightCorner,
  98. BottomLeftCorner
  99. };
  100. /** Set the name of the window */
  101. virtual void setWindowName(const std::string& /*name*/) { osg::notify(osg::NOTICE)<<"GraphicsWindow::setWindowName(..) not implemented."<<std::endl; }
  102. /** Return the name of the window */
  103. virtual std::string getWindowName() { return _traits.valid() ? _traits->windowName : ""; }
  104. /** Switch on/off the cursor.*/
  105. virtual void useCursor(bool cursorOn) { setCursor(cursorOn ? InheritCursor : NoCursor); }
  106. /** Set mouse cursor to a specific shape.*/
  107. virtual void setCursor(MouseCursor /*mouseCursor*/) { osg::notify(osg::NOTICE)<<"GraphicsWindow::setCursor(..) not implemented."<<std::endl; }
  108. /** Create a new mouse cursor from the usual bitmap data.*/
  109. //virtual MouseCursor createCursor(const char *data, const char *mask, unsigned w, unsigned h, unsigned hotx, unsigned hoty) { osg::notify(osg::NOTICE)<<"GraphicsWindow::createCursor(..) not implemented."<<std::endl; }
  110. /** Set sync-to-vblank. */
  111. virtual void setSyncToVBlank(bool on)
  112. {
  113. osg::notify(osg::NOTICE) << "GraphicsWindow::setSyncToVBlank(" << on << ") not implemented." << std::endl;
  114. }
  115. bool getSyncToVBlank() const { return _traits.valid() ? _traits->vsync : true; }
  116. /** Set swap group. */
  117. virtual void setSwapGroup(bool on, GLuint group, GLuint barrier)
  118. {
  119. osg::notify(osg::NOTICE) << "GraphicsWindow::setSwapGroup(" << on << " " << group << " " << barrier << ") not implemented." << std::endl;
  120. }
  121. void getSwapGroup(bool& on, GLuint& group, GLuint& barrier) const { on = _traits->swapGroupEnabled; group = _traits->swapGroup; barrier = _traits->swapBarrier; }
  122. public:
  123. /** Return whether a valid and usable GraphicsContext has been created.*/
  124. virtual bool valid() const { osg::notify(osg::NOTICE)<<"GraphicsWindow::valid() not implemented."<<std::endl; return false; }
  125. /** Realize the GraphicsContext implementation,
  126. * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
  127. virtual bool realizeImplementation() { osg::notify(osg::NOTICE)<<"GraphicsWindow::realizeImplementation() not implemented."<<std::endl; return false; }
  128. /** Return true if the graphics context has been realized, and is ready to use, implementation.
  129. * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
  130. virtual bool isRealizedImplementation() const { osg::notify(osg::NOTICE)<<"GraphicsWindow::isRealizedImplementation() not implemented."<<std::endl; return false; }
  131. /** Close the graphics context implementation.
  132. * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
  133. virtual void closeImplementation() { osg::notify(osg::NOTICE)<<"GraphicsWindow::closeImplementation() not implemented."<<std::endl; }
  134. /** Make this graphics context current implementation.
  135. * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
  136. virtual bool makeCurrentImplementation() { osg::notify(osg::NOTICE)<<"GraphicsWindow::makeCurrentImplementation() not implemented."<<std::endl; return false;}
  137. /** Make this graphics context current with specified read context implementation.
  138. * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
  139. virtual bool makeContextCurrentImplementation(GraphicsContext* /*readContext*/) { osg::notify(osg::NOTICE)<<"GraphicsWindow::makeContextCurrentImplementation(..) not implemented."<<std::endl; return false;}
  140. /** Release the graphics context.*/
  141. virtual bool releaseContextImplementation() { osg::notify(osg::NOTICE)<<"GraphicsWindow::releaseContextImplementation(..) not implemented."<<std::endl; return false; }
  142. /** Pure virtual, Bind the graphics context to associated texture implementation.
  143. * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
  144. virtual void bindPBufferToTextureImplementation(GLenum /*buffer*/) { osg::notify(osg::NOTICE)<<"GraphicsWindow::bindPBufferToTextureImplementation(..) not implemented."<<std::endl; }
  145. /** Swap the front and back buffers implementation.
  146. * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
  147. virtual void swapBuffersImplementation() { osg::notify(osg::NOTICE)<<"GraphicsWindow:: swapBuffersImplementation() not implemented."<<std::endl; }
  148. public:
  149. typedef std::list<osgViewer::View*> Views;
  150. /** Returns the list of views (osgViewer::View) attached to this GraphicsWindow.
  151. * Internally, the method walks through all the cameras and collects all the views attached to the cameras.*/
  152. void getViews(Views& views);
  153. // Override from GUIActionAdapter
  154. virtual void requestRedraw();
  155. // Override from GUIActionAdapter
  156. virtual void requestContinuousUpdate(bool /*needed*/=true) {}
  157. // Override from GUIActionAdapter
  158. virtual void requestWarpPointer(float /*x*/,float /*y*/) {}
  159. protected:
  160. osg::ref_ptr<osgGA::EventQueue> _eventQueue;
  161. };
  162. class GraphicsWindowEmbedded : public GraphicsWindow
  163. {
  164. public:
  165. GraphicsWindowEmbedded(osg::GraphicsContext::Traits* traits=0)
  166. {
  167. _traits = traits;
  168. init();
  169. }
  170. GraphicsWindowEmbedded(int x, int y, int width, int height)
  171. {
  172. _traits = new GraphicsContext::Traits;
  173. _traits->x = x;
  174. _traits->y = y;
  175. _traits->width = width;
  176. _traits->height = height;
  177. init();
  178. }
  179. virtual bool isSameKindAs(const Object* object) const { return dynamic_cast<const GraphicsWindowEmbedded*>(object)!=0; }
  180. virtual const char* libraryName() const { return "osgViewer"; }
  181. virtual const char* className() const { return "GraphicsWindowEmbedded"; }
  182. void init()
  183. {
  184. if (valid())
  185. {
  186. setState( new osg::State );
  187. getState()->setGraphicsContext(this);
  188. if (_traits.valid() && _traits->sharedContext.valid())
  189. {
  190. getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
  191. incrementContextIDUsageCount( getState()->getContextID() );
  192. }
  193. else
  194. {
  195. getState()->setContextID( osg::GraphicsContext::createNewContextID() );
  196. }
  197. }
  198. }
  199. // dummy implementations, assume that graphics context is *always* current and valid.
  200. virtual bool valid() const { return true; }
  201. virtual bool realizeImplementation() { return true; }
  202. virtual bool isRealizedImplementation() const { return true; }
  203. virtual void closeImplementation() {}
  204. virtual bool makeCurrentImplementation() { return true; }
  205. virtual bool releaseContextImplementation() { return true; }
  206. virtual void swapBuffersImplementation() {}
  207. virtual void grabFocus() {}
  208. virtual void grabFocusIfPointerInWindow() {}
  209. virtual void raiseWindow() {}
  210. };
  211. struct GraphicsWindowFunctionProxy
  212. {
  213. GraphicsWindowFunctionProxy(CGraphicsWindowFunction function) { (function)(); }
  214. };
  215. #define USE_GRAPICSWINDOW_IMPLEMENTATION(ext) \
  216. extern "C" void graphicswindow_##ext(void); \
  217. static osgViewer::GraphicsWindowFunctionProxy graphicswindowproxy_##ext(graphicswindow_##ext);
  218. #if defined(_WIN32)
  219. #define USE_GRAPHICSWINDOW() USE_GRAPICSWINDOW_IMPLEMENTATION(Win32)
  220. #elif defined(__APPLE__)
  221. #if defined(OSG_WINDOWING_SYSTEM_CARBON)
  222. #define USE_GRAPHICSWINDOW() USE_GRAPICSWINDOW_IMPLEMENTATION(Carbon)
  223. #else
  224. #define USE_GRAPHICSWINDOW() USE_GRAPICSWINDOW_IMPLEMENTATION(Cocoa)
  225. #endif
  226. #else
  227. #define USE_GRAPHICSWINDOW() USE_GRAPICSWINDOW_IMPLEMENTATION(X11)
  228. #endif
  229. }
  230. #endif