123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606 |
- /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
- *
- * This library is open source and may be redistributed and/or modified under
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
- * (at your option) any later version. The full license is in LICENSE file
- * included with this distribution, and on the openscenegraph.org website.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * OpenSceneGraph Public License for more details.
- */
- #ifndef OSG_GRAPHICSCONTEXT
- #define OSG_GRAPHICSCONTEXT 1
- #include <osg/State>
- #include <osg/GraphicsThread>
- #include <osg/Timer>
- #include <vector>
- namespace osg {
- // forward declare osg::Camera
- class Camera;
- /** Base class for providing Windowing API agnostic access to creating and managing graphics context.*/
- class OSG_EXPORT GraphicsContext : public Object
- {
- public:
- struct OSG_EXPORT ScreenIdentifier
- {
- ScreenIdentifier();
- ScreenIdentifier(int in_screenNum);
- ScreenIdentifier(const std::string& in_hostName,int in_displayNum, int in_screenNum);
- /** Return the display name in the form hostName::displayNum:screenNum. */
- std::string displayName() const;
- /** Read the DISPLAY environmental variable, and set the ScreenIdentifier accordingly.
- * Note, if either of displayNum or screenNum are not defined then -1 is set respectively to
- * signify that this parameter has not been set. When parameters are undefined one can call
- * call setUndefinedScreenDetailsToDefaultScreen() after readDISPLAY() to ensure valid values. */
- void readDISPLAY();
- /** Set the screenIndentifier from the displayName string.
- * Note, if either of displayNum or screenNum are not defined then -1 is set to
- * signify that this parameter has not been set. When parameters are undefined one can call
- * call setUndefinedScreenDetailsToDefaultScreen() after readDISPLAY() to ensure valid values. */
- void setScreenIdentifier(const std::string& displayName);
- /** Set any undefined displayNum or screenNum values (i.e. -1) to the default display & screen of 0 respectively.*/
- void setUndefinedScreenDetailsToDefaultScreen()
- {
- if (displayNum<0) displayNum = 0;
- if (screenNum<0) screenNum = 0;
- }
- std::string hostName;
- int displayNum;
- int screenNum;
- };
- /** GraphicsContext Traits object provides the specification of what type of graphics context is required.*/
- struct OSG_EXPORT Traits : public osg::Referenced, public ScreenIdentifier
- {
- Traits(DisplaySettings* ds=0);
- // graphics context original and size
- int x;
- int y;
- int width;
- int height;
- // provide a hint as to which WindowingSystemInterface implementation to use, i.e. "X11", "Win32", "Cocoa", "Carbon" etc.
- // if the windowingSystemPreference string is empty (default) then return the first available WindowingSystemInterface that
- // has been registered with the osg::GraphiccsContext::WindowingSystemInterfaces singleton
- // if the windowingSystemPreference string is not empty then return the first WindowingSystemInterface that matches
- std::string windowingSystemPreference;
- // window decoration and behaviour
- std::string windowName;
- bool windowDecoration;
- bool supportsResize;
- // buffer depths, 0 equals off.
- unsigned int red;
- unsigned int blue;
- unsigned int green;
- unsigned int alpha;
- unsigned int depth;
- unsigned int stencil;
- // multi sample parameters
- unsigned int sampleBuffers;
- unsigned int samples;
- // buffer configuration
- bool pbuffer;
- bool quadBufferStereo;
- bool doubleBuffer;
- // render to texture
- GLenum target;
- GLenum format;
- unsigned int level;
- unsigned int face;
- unsigned int mipMapGeneration;
- // V-sync
- bool vsync;
- // Swap Group
- bool swapGroupEnabled;
- GLuint swapGroup;
- GLuint swapBarrier;
- // use multithreaded OpenGL-engine (OS X only)
- bool useMultiThreadedOpenGLEngine;
- // enable cursor
- bool useCursor;
- // settings used in set up of graphics context, only presently used by GL3 build of OSG.
- std::string glContextVersion;
- unsigned int glContextFlags;
- unsigned int glContextProfileMask;
- /** return true if glContextVersion is set in the form major.minor, and assign the appropriate major and minor values to the associated parameters.*/
- bool getContextVersion(unsigned int& major, unsigned int& minor) const;
- // shared context
- osg::observer_ptr<GraphicsContext> sharedContext;
- osg::ref_ptr<osg::Referenced> inheritedWindowData;
- // ask the GraphicsWindow implementation to set the pixel format of an inherited window
- bool setInheritedWindowPixelFormat;
- // X11 hint whether to override the window managers window size/position redirection
- bool overrideRedirect;
- DisplaySettings::SwapMethod swapMethod;
- // hint of what affinity to use for any thrads associated with the graphics context created using these Traits
- OpenThreads::Affinity affinity;
- };
- /** Simple resolution structure used by WindowingSystemInterface to get and set screen resolution.
- * Note the '0' value stands for 'unset'. */
- struct ScreenSettings {
- ScreenSettings() :
- width(0),
- height(0),
- refreshRate(0),
- colorDepth(0)
- {}
- ScreenSettings(int in_width, int in_height, double in_refreshRate=0, unsigned int in_colorDepth=0) :
- width(in_width),
- height(in_height),
- refreshRate(in_refreshRate),
- colorDepth(in_colorDepth)
- {}
- int width;
- int height;
- double refreshRate; ///< Screen refresh rate, in Hz.
- unsigned int colorDepth; ///< RGB(A) color buffer depth.
- };
- typedef std::vector<ScreenSettings> ScreenSettingsList;
- /** Callback to be implemented to provide access to Windowing API's ability to create Windows/pbuffers.*/
- struct WindowingSystemInterface : public osg::Referenced
- {
- void setName(const std::string& name) { _name = name; }
- const std::string& getName() const { return _name; }
- virtual unsigned int getNumScreens(const ScreenIdentifier& screenIdentifier = ScreenIdentifier()) = 0;
- virtual void getScreenSettings(const ScreenIdentifier& screenIdentifier, ScreenSettings & resolution) = 0;
- virtual bool setScreenSettings(const ScreenIdentifier& /*screenIdentifier*/, const ScreenSettings & /*resolution*/) { return false; }
- virtual void enumerateScreenSettings(const ScreenIdentifier& screenIdentifier, ScreenSettingsList & resolutionList) = 0;
- virtual void setDisplaySettings(DisplaySettings*) {}
- virtual osg::DisplaySettings* getDisplaySettings() const { return 0; }
- virtual GraphicsContext* createGraphicsContext(Traits* traits) = 0;
- /** Gets screen resolution without using the ScreenResolution structure.
- * \deprecated Provided only for backward compatibility. */
- inline void getScreenResolution(const ScreenIdentifier& screenIdentifier, unsigned int& width, unsigned int& height)
- {
- ScreenSettings settings;
- getScreenSettings(screenIdentifier, settings);
- width = settings.width;
- height = settings.height;
- }
- /** Sets screen resolution without using the ScreenSettings structure.
- * \deprecated Provided only for backward compatibility. */
- inline bool setScreenResolution(const ScreenIdentifier& screenIdentifier, unsigned int width, unsigned int height)
- {
- return setScreenSettings(screenIdentifier, ScreenSettings(width, height));
- }
- /** \deprecated Provided only for backward compatibility. */
- inline bool setScreenRefreshRate(const ScreenIdentifier& screenIdentifier, double refreshRate)
- {
- ScreenSettings settings;
- getScreenSettings(screenIdentifier, settings);
- settings.refreshRate = refreshRate;
- return setScreenSettings(screenIdentifier, settings);
- }
- protected:
- WindowingSystemInterface() {}
- virtual ~WindowingSystemInterface() {}
- std::string _name;
- };
- class OSG_EXPORT WindowingSystemInterfaces : public osg::Referenced
- {
- public:
- WindowingSystemInterfaces();
- typedef std::vector< osg::ref_ptr<GraphicsContext::WindowingSystemInterface> > Interfaces;
- Interfaces& getInterfaces() { return _interfaces; }
- void addWindowingSystemInterface(WindowingSystemInterface* wsInterface);
- void removeWindowingSystemInterface(WindowingSystemInterface* wsInterface);
- /** get named WindowingSystemInterface if one is available, otherwise return 0; */
- WindowingSystemInterface* getWindowingSystemInterface(const std::string& name = "");
- private:
- virtual ~WindowingSystemInterfaces();
- Interfaces _interfaces;
- };
- static osg::ref_ptr<WindowingSystemInterfaces>& getWindowingSystemInterfaces();
- /** Get the default WindowingSystemInterface for this OS*/
- static WindowingSystemInterface* getWindowingSystemInterface(const std::string& name = "");
- /** Create a graphics context for a specified set of traits.*/
- static GraphicsContext* createGraphicsContext(Traits* traits);
- /** Create a contextID for a new graphics context, this contextID is used to set up the osg::State associate with context.
- * Automatically increments the usage count of the contextID to 1.*/
- static unsigned int createNewContextID();
- /** Get the current max ContextID.*/
- static unsigned int getMaxContextID();
- /** Increment the usage count associate with a contextID. The usage count specifies how many graphics contexts a specific contextID is shared between.*/
- static void incrementContextIDUsageCount(unsigned int contextID);
- /** Decrement the usage count associate with a contextID. Once the contextID goes to 0 the contextID is then free to be reused.*/
- static void decrementContextIDUsageCount(unsigned int contextID);
- typedef std::vector<GraphicsContext*> GraphicsContexts;
- /** Get all the registered graphics contexts.*/
- static GraphicsContexts getAllRegisteredGraphicsContexts();
- /** Get all the registered graphics contexts associated with a specific contextID.*/
- static GraphicsContexts getRegisteredGraphicsContexts(unsigned int contextID);
- /** Get the GraphicsContext for doing background compilation for GraphicsContexts associated with specified contextID.*/
- static void setCompileContext(unsigned int contextID, GraphicsContext* gc);
- /** Get existing or create a new GraphicsContext to do background compilation for GraphicsContexts associated with specified contextID.*/
- static GraphicsContext* getOrCreateCompileContext(unsigned int contextID);
- /** Get the GraphicsContext for doing background compilation for GraphicsContexts associated with specified contextID.*/
- static GraphicsContext* getCompileContext(unsigned int contextID);
- public:
- /** Add operation to end of OperationQueue.*/
- void add(Operation* operation);
- /** Remove operation from OperationQueue.*/
- void remove(Operation* operation);
- /** Remove named operation from OperationQueue.*/
- void remove(const std::string& name);
- /** Remove all operations from OperationQueue.*/
- void removeAllOperations();
- /** Run the operations. */
- virtual void runOperations();
- typedef std::list< ref_ptr<Operation> > GraphicsOperationQueue;
- /** Get the operations queue, note you must use the OperationsMutex when accessing the queue.*/
- GraphicsOperationQueue& getOperationsQueue() { return _operations; }
- /** Get the operations queue mutex.*/
- OpenThreads::Mutex* getOperationsMutex() { return &_operationsMutex; }
- /** Get the operations queue block used to mark an empty queue, if you end items into the empty queue you must release this block.*/
- osg::RefBlock* getOperationsBlock() { return _operationsBlock.get(); }
- /** Get the current operations that is being run.*/
- Operation* getCurrentOperation() { return _currentOperation.get(); }
- public:
- /** Get the traits of the GraphicsContext.*/
- inline const Traits* getTraits() const { return _traits.get(); }
- /** Return whether a valid and usable GraphicsContext has been created.*/
- virtual bool valid() const = 0;
- /** Set the State object which tracks the current OpenGL state for this graphics context.*/
- inline void setState(State* state) { _state = state; }
- /** Get the State object which tracks the current OpenGL state for this graphics context.*/
- inline State* getState() { return _state.get(); }
- /** Get the const State object which tracks the current OpenGL state for this graphics context.*/
- inline const State* getState() const { return _state.get(); }
- /** Sets the clear color. */
- inline void setClearColor(const Vec4& color) { _clearColor = color; }
- /** Returns the clear color. */
- inline const Vec4& getClearColor() const { return _clearColor; }
- /** Set the clear mask used in glClear(..).
- * Defaults to 0 - so no clear is done by default by the GraphicsContext, instead the Cameras attached to the GraphicsContext will do the clear.
- * GraphicsContext::setClearMask() is useful for when the Camera Viewports don't cover the whole context, so the context will fill in the gaps. */
- inline void setClearMask(GLbitfield mask) { _clearMask = mask; }
- /** Get the clear mask.*/
- inline GLbitfield getClearMask() const { return _clearMask; }
- /** Do an OpenGL clear of the full graphics context/window.
- * Note, must only be called from a thread with this context current.*/
- virtual void clear();
- double getTimeSinceLastClear() const { return osg::Timer::instance()->delta_s(_lastClearTick, osg::Timer::instance()->tick()); }
- /** Realize the GraphicsContext.*/
- bool realize();
- /** close the graphics context.
- * close(bool) stops any associated graphics threads, releases the contextID for the GraphicsContext then
- * optional calls closeImplementation() to do the actual deletion of the graphics. This call is made optional
- * as there are times when the graphics context has already been deleted externally and only the OSG side
- * of the its data need to be closed down. */
- void close(bool callCloseImplementation=true);
- /** swap the front and back buffers.*/
- void swapBuffers();
- /** Return true if the graphics context has been realized and is ready to use.*/
- inline bool isRealized() const { return isRealizedImplementation(); }
- /** Make this graphics context current.
- * Implemented by calling makeCurrentImplementation().
- * Returns true on success. */
- bool makeCurrent();
- /** Make this graphics context current with specified read context.
- * Implemented by calling makeContextCurrentImplementation().
- * Returns true on success. */
- bool makeContextCurrent(GraphicsContext* readContext);
- /** Release the graphics context.
- * Returns true on success. */
- bool releaseContext();
- /** Return true if the current thread has this OpenGL graphics context.*/
- inline bool isCurrent() const { return _threadOfLastMakeCurrent == OpenThreads::Thread::CurrentThreadId(); }
- /** Bind the graphics context to associated texture.*/
- inline void bindPBufferToTexture(GLenum buffer) { bindPBufferToTextureImplementation(buffer); }
- /** Create a graphics thread to the graphics context, so that the thread handles all OpenGL operations.*/
- void createGraphicsThread();
- /** Assign a graphics thread to the graphics context, so that the thread handles all OpenGL operations.*/
- void setGraphicsThread(GraphicsThread* gt);
- /** Get the graphics thread assigned the graphics context.*/
- GraphicsThread* getGraphicsThread() { return _graphicsThread.get(); }
- /** Get the const graphics thread assigned the graphics context.*/
- const GraphicsThread* getGraphicsThread() const { return _graphicsThread.get(); }
- /** Realize the GraphicsContext implementation,
- * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
- virtual bool realizeImplementation() = 0;
- /** Return true if the graphics context has been realized, and is ready to use, implementation.
- * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
- virtual bool isRealizedImplementation() const = 0;
- /** Close the graphics context implementation.
- * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
- virtual void closeImplementation() = 0;
- /** Make this graphics context current implementation.
- * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
- virtual bool makeCurrentImplementation() = 0;
- /** Make this graphics context current with specified read context implementation.
- * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
- virtual bool makeContextCurrentImplementation(GraphicsContext* readContext) = 0;
- /** Release the graphics context implementation.*/
- virtual bool releaseContextImplementation() = 0;
- /** Pure virtual, Bind the graphics context to associated texture implementation.
- * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
- virtual void bindPBufferToTextureImplementation(GLenum buffer) = 0;
- struct SwapCallback : public osg::Referenced
- {
- virtual void swapBuffersImplementation(GraphicsContext* gc) = 0;
- };
- /** Set the swap callback which overrides the
- * GraphicsContext::swapBuffersImplementation(), allowing
- * developers to provide custom behavior for swap.
- * The callback must call
- * GraphicsContext::swapBuffersImplementation() */
- void setSwapCallback(SwapCallback* rc) { _swapCallback = rc; }
- /** Get the swap callback which overrides the GraphicsContext::swapBuffersImplementation().*/
- SwapCallback* getSwapCallback() { return _swapCallback.get(); }
- /** Get the const swap callback which overrides the GraphicsContext::swapBuffersImplementation().*/
- const SwapCallback* getSwapCallback() const { return _swapCallback.get(); }
- /** Convenience method for handling whether to call swapbuffers callback or the standard context swapBuffersImplementation.
- * swapBuffersCallbackOrImplementation() is called by swapBuffers() and osg::SwapBuffersOperation, end users should normally
- * call swapBuffers() rather than swapBuffersCallbackOrImplementation(). */
- void swapBuffersCallbackOrImplementation()
- {
- if (_state.valid()) _state->frameCompleted();
- if (_swapCallback.valid()) _swapCallback->swapBuffersImplementation(this);
- else swapBuffersImplementation();
- }
- /** Swap the front and back buffers implementation.
- * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
- virtual void swapBuffersImplementation() = 0;
- /** resized method should be called when the underlying window has been resized and the GraphicsWindow and associated Cameras must
- be updated to keep in sync with the new size. */
- void resized(int x, int y, int width, int height)
- {
- if (_resizedCallback.valid()) _resizedCallback->resizedImplementation(this, x, y, width, height);
- else resizedImplementation(x, y, width, height);
- }
- struct ResizedCallback : public osg::Referenced
- {
- virtual void resizedImplementation(GraphicsContext* gc, int x, int y, int width, int height) = 0;
- };
- /** Set the resized callback which overrides the GraphicsConext::realizedImplementation(), allow developers to provide custom behavior
- * in response to a window being resized.*/
- void setResizedCallback(ResizedCallback* rc) { _resizedCallback = rc; }
- /** Get the resized callback which overrides the GraphicsConext::realizedImplementation().*/
- ResizedCallback* getResizedCallback() { return _resizedCallback.get(); }
- /** Get the const resized callback which overrides the GraphicsConext::realizedImplementation().*/
- const ResizedCallback* getResizedCallback() const { return _resizedCallback.get(); }
- /** resized implementation, by default resizes the viewports and aspect ratios the cameras associated with the graphics Window. */
- virtual void resizedImplementation(int x, int y, int width, int height);
- typedef std::list< osg::Camera* > Cameras;
- /** Get the list of cameras associated with this graphics context.*/
- Cameras& getCameras() { return _cameras; }
- /** Get the const list of cameras associated with this graphics context.*/
- const Cameras& getCameras() const { return _cameras; }
- /** set the default FBO-id, this id will be used when the rendering-backend is finished with RTT FBOs */
- void setDefaultFboId(GLuint i) { _defaultFboId = i; }
- GLuint getDefaultFboId() const { return _defaultFboId; }
- public:
- virtual bool isSameKindAs(const Object* object) const { return dynamic_cast<const GraphicsContext*>(object)!=0; }
- virtual const char* libraryName() const { return "osg"; }
- virtual const char* className() const { return "GraphicsContext"; }
- protected:
- GraphicsContext();
- GraphicsContext(const GraphicsContext&, const osg::CopyOp&);
- virtual ~GraphicsContext();
- virtual Object* cloneType() const { return 0; }
- virtual Object* clone(const CopyOp&) const { return 0; }
- /** Register a GraphicsContext.*/
- static void registerGraphicsContext(GraphicsContext* gc);
- /** Unregister a GraphicsContext.*/
- static void unregisterGraphicsContext(GraphicsContext* gc);
- void addCamera(osg::Camera* camera);
- void removeCamera(osg::Camera* camera);
- Cameras _cameras;
- friend class osg::Camera;
- ref_ptr<Traits> _traits;
- ref_ptr<State> _state;
- Vec4 _clearColor;
- GLbitfield _clearMask;
- size_t _threadOfLastMakeCurrent;
- OpenThreads::Mutex _operationsMutex;
- osg::ref_ptr<osg::RefBlock> _operationsBlock;
- GraphicsOperationQueue _operations;
- osg::ref_ptr<Operation> _currentOperation;
- ref_ptr<GraphicsThread> _graphicsThread;
- ref_ptr<ResizedCallback> _resizedCallback;
- ref_ptr<SwapCallback> _swapCallback;
- Timer_t _lastClearTick;
- GLuint _defaultFboId;
- };
- //#include <osg/GLExtensions>
- class OSG_EXPORT SyncSwapBuffersCallback : public GraphicsContext::SwapCallback
- {
- public:
- SyncSwapBuffersCallback();
- virtual void swapBuffersImplementation(GraphicsContext* gc);
- GLsync _previousSync;
- };
- template<class T>
- struct WindowingSystemInterfaceProxy
- {
- WindowingSystemInterfaceProxy(const std::string& name)
- {
- _wsi = new T;
- _wsi->setName(name);
- osg::GraphicsContext::getWindowingSystemInterfaces()->addWindowingSystemInterface(_wsi.get());
- }
- ~WindowingSystemInterfaceProxy()
- {
- osg::GraphicsContext::getWindowingSystemInterfaces()->removeWindowingSystemInterface(_wsi.get());
- }
- osg::ref_ptr<T> _wsi;
- };
- #define REGISTER_WINDOWINGSYSTEMINTERFACE(ext, classname) \
- extern "C" void graphicswindow_##ext(void) {} \
- static osg::WindowingSystemInterfaceProxy<classname> s_proxy_##classname(#ext);
- }
- #endif
|