2006-07-18 23:21:48 +08:00
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2005-07-21 16:43:24 +08:00
*
* 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>
2005-08-19 04:17:51 +08:00
#include <osg/GraphicsThread>
2009-03-12 23:18:51 +08:00
#include <osg/Timer>
2008-12-16 23:08:04 +08:00
#include <vector>
2005-08-18 17:36:40 +08:00
2005-07-21 16:43:24 +08:00
namespace osg {
2007-01-02 02:20:10 +08:00
// forward declare osg::Camera
class Camera;
2005-07-25 22:28:22 +08:00
/** Base class for providing Windowing API agnostic access to creating and managing graphics context.*/
2007-02-03 06:30:36 +08:00
class OSG_EXPORT GraphicsContext : public Object
2005-07-21 16:43:24 +08:00
{
public:
2012-03-22 01:36:20 +08:00
2006-12-23 05:53:44 +08:00
struct OSG_EXPORT ScreenIdentifier
2006-12-18 04:49:01 +08:00
{
2007-08-03 22:50:58 +08:00
ScreenIdentifier();
2006-12-20 00:00:51 +08:00
2007-08-03 22:50:58 +08:00
ScreenIdentifier(int in_screenNum);
2006-12-20 00:00:51 +08:00
2007-08-03 22:50:58 +08:00
ScreenIdentifier(const std::string& in_hostName,int in_displayNum, int in_screenNum);
2012-03-22 01:36:20 +08:00
/** Return the display name in the form hostName::displayNum:screenNum. */
2006-12-23 05:53:44 +08:00
std::string displayName() const;
2012-03-22 01:36:20 +08:00
2008-01-04 21:57:36 +08:00
/** 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
2011-09-12 20:04:46 +08:00
* signify that this parameter has not been set. When parameters are undefined one can call
* call setUndefinedScreenDetailsToDefaultScreen() after readDISPLAY() to ensure valid values. */
2007-08-03 22:50:58 +08:00
void readDISPLAY();
2012-03-22 01:36:20 +08:00
2008-01-04 21:57:36 +08:00
/** Set the screenIndentifier from the displayName string.
2011-09-12 20:04:46 +08:00
* 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. */
2007-08-03 22:50:58 +08:00
void setScreenIdentifier(const std::string& displayName);
2006-12-23 05:53:44 +08:00
2008-01-04 21:57:36 +08:00
/** 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;
}
2006-12-23 05:53:44 +08:00
std::string hostName;
2007-08-03 22:50:58 +08:00
int displayNum;
int screenNum;
2006-12-18 04:49:01 +08:00
};
2012-03-22 01:36:20 +08:00
2005-07-25 22:28:22 +08:00
/** GraphicsContext Traits object provides the specification of what type of graphics context is required.*/
2009-11-13 17:56:47 +08:00
struct OSG_EXPORT Traits : public osg::Referenced, public ScreenIdentifier
2005-07-21 16:43:24 +08:00
{
2009-11-11 23:25:42 +08:00
Traits(DisplaySettings* ds=0);
2012-03-22 01:36:20 +08:00
2007-12-11 01:30:18 +08:00
// graphics context original and size
2007-01-02 02:20:10 +08:00
int x;
int y;
int width;
int height;
2012-03-22 01:36:20 +08:00
2016-05-16 20:45:31 +08:00
// 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;
2007-12-11 01:30:18 +08:00
// window decoration and behaviour
2006-12-23 05:53:44 +08:00
std::string windowName;
bool windowDecoration;
bool supportsResize;
2012-03-22 01:36:20 +08:00
2005-07-21 16:43:24 +08:00
// buffer depths, 0 equals off.
2006-12-23 05:53:44 +08:00
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;
2005-07-21 16:43:24 +08:00
// buffer configuration
2006-12-23 05:53:44 +08:00
bool pbuffer;
bool quadBufferStereo;
bool doubleBuffer;
2005-07-21 16:43:24 +08:00
// render to texture
2006-12-23 05:53:44 +08:00
GLenum target;
2007-06-27 18:12:10 +08:00
GLenum format;
2006-12-23 05:53:44 +08:00
unsigned int level;
unsigned int face;
unsigned int mipMapGeneration;
2012-03-22 01:36:20 +08:00
2007-01-09 18:06:20 +08:00
// V-sync
bool vsync;
2012-03-22 01:36:20 +08:00
2011-04-21 21:34:03 +08:00
// Swap Group
bool swapGroupEnabled;
GLuint swapGroup;
GLuint swapBarrier;
2007-02-16 21:33:29 +08:00
// use multithreaded OpenGL-engine (OS X only)
bool useMultiThreadedOpenGLEngine;
2012-03-22 01:36:20 +08:00
2007-01-18 05:11:57 +08:00
// enable cursor
bool useCursor;
2009-11-11 23:25:42 +08:00
// 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;
2012-03-21 19:36:54 +08:00
/** 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;
2012-03-22 01:36:20 +08:00
2005-07-21 16:43:24 +08:00
// shared context
2012-09-06 05:03:41 +08:00
osg::observer_ptr<GraphicsContext> sharedContext;
2012-03-22 01:36:20 +08:00
2007-03-16 21:22:05 +08:00
osg::ref_ptr<osg::Referenced> inheritedWindowData;
2012-03-22 01:36:20 +08:00
2007-05-17 18:33:44 +08:00
// ask the GraphicsWindow implementation to set the pixel format of an inherited window
bool setInheritedWindowPixelFormat;
2012-03-22 01:36:20 +08:00
2008-06-22 01:50:58 +08:00
// X11 hint whether to override the window managers window size/position redirection
bool overrideRedirect;
2010-09-30 22:25:27 +08:00
DisplaySettings::SwapMethod swapMethod;
2016-09-29 01:44:58 +08:00
// hint of what affinity to use for any thrads associated with the graphics context created using these Traits
OpenThreads::Affinity affinity;
2005-07-21 16:43:24 +08:00
};
2008-12-16 23:08:04 +08:00
/** 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),
2008-12-17 19:00:16 +08:00
refreshRate(0),
colorDepth(0)
2008-12-16 23:08:04 +08:00
{}
2016-05-20 20:38:34 +08:00
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)
2008-12-16 23:08:04 +08:00
{}
int width;
int height;
double refreshRate; ///< Screen refresh rate, in Hz.
unsigned int colorDepth; ///< RGB(A) color buffer depth.
};
typedef std::vector<ScreenSettings> ScreenSettingsList;
2005-07-25 22:28:22 +08:00
/** Callback to be implemented to provide access to Windowing API's ability to create Windows/pbuffers.*/
2006-12-18 04:49:01 +08:00
struct WindowingSystemInterface : public osg::Referenced
2005-07-21 16:43:24 +08:00
{
2016-05-16 20:45:31 +08:00
void setName(const std::string& name) { _name = name; }
const std::string& getName() const { return _name; }
2006-12-18 04:49:01 +08:00
virtual unsigned int getNumScreens(const ScreenIdentifier& screenIdentifier = ScreenIdentifier()) = 0;
2008-12-16 23:08:04 +08:00
virtual void getScreenSettings(const ScreenIdentifier& screenIdentifier, ScreenSettings & resolution) = 0;
2007-01-18 05:11:57 +08:00
2008-12-16 23:08:04 +08:00
virtual bool setScreenSettings(const ScreenIdentifier& /*screenIdentifier*/, const ScreenSettings & /*resolution*/) { return false; }
virtual void enumerateScreenSettings(const ScreenIdentifier& screenIdentifier, ScreenSettingsList & resolutionList) = 0;
2007-01-18 05:11:57 +08:00
2013-10-23 03:12:34 +08:00
virtual void setDisplaySettings(DisplaySettings*) {}
virtual osg::DisplaySettings* getDisplaySettings() const { return 0; }
2005-07-21 16:43:24 +08:00
virtual GraphicsContext* createGraphicsContext(Traits* traits) = 0;
2012-03-22 01:36:20 +08:00
2008-12-16 23:08:04 +08:00
/** 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);
}
2016-05-16 20:45:31 +08:00
protected:
WindowingSystemInterface() {}
virtual ~WindowingSystemInterface() {}
2013-10-23 03:12:34 +08:00
2016-05-16 20:45:31 +08:00
std::string _name;
2005-07-21 16:43:24 +08:00
};
2012-03-22 01:36:20 +08:00
2016-05-16 20:45:31 +08:00
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);
2012-03-22 01:36:20 +08:00
2016-05-16 20:45:31 +08:00
/** get named WindowingSystemInterface if one is available, otherwise return 0; */
WindowingSystemInterface* getWindowingSystemInterface(const std::string& name = "");
2012-03-22 01:36:20 +08:00
2016-05-16 20:45:31 +08:00
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 = "");
2012-03-22 01:36:20 +08:00
2005-07-25 22:28:22 +08:00
/** Create a graphics context for a specified set of traits.*/
2005-07-21 16:43:24 +08:00
static GraphicsContext* createGraphicsContext(Traits* traits);
2012-03-22 01:36:20 +08:00
2005-07-25 22:28:22 +08:00
/** 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();
2007-07-06 02:33:20 +08:00
/** Get the current max ContextID.*/
static unsigned int getMaxContextID();
2007-12-11 01:30:18 +08:00
/** Increment the usage count associate with a contextID. The usage count specifies how many graphics contexts a specific contextID is shared between.*/
2005-07-25 22:28:22 +08:00
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);
2012-03-22 01:36:20 +08:00
2007-07-06 02:33:20 +08:00
typedef std::vector<GraphicsContext*> GraphicsContexts;
2012-03-22 01:36:20 +08:00
2007-07-06 02:33:20 +08:00
/** Get all the registered graphics contexts.*/
static GraphicsContexts getAllRegisteredGraphicsContexts();
2012-03-22 01:36:20 +08:00
2007-07-06 02:33:20 +08:00
/** Get all the registered graphics contexts associated with a specific contextID.*/
static GraphicsContexts getRegisteredGraphicsContexts(unsigned int contextID);
2012-03-22 01:36:20 +08:00
2007-07-06 02:33:20 +08:00
/** 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);
2012-03-22 01:36:20 +08:00
2007-07-06 02:33:20 +08:00
/** Get the GraphicsContext for doing background compilation for GraphicsContexts associated with specified contextID.*/
static GraphicsContext* getCompileContext(unsigned int contextID);
2006-12-22 00:56:20 +08:00
public:
2012-03-22 01:36:20 +08:00
2006-12-22 00:56:20 +08:00
/** Add operation to end of OperationQueue.*/
2007-02-03 06:30:36 +08:00
void add(Operation* operation);
2012-03-22 01:36:20 +08:00
2006-12-22 00:56:20 +08:00
/** Remove operation from OperationQueue.*/
2007-02-03 06:30:36 +08:00
void remove(Operation* operation);
2006-12-22 00:56:20 +08:00
/** Remove named operation from OperationQueue.*/
void remove(const std::string& name);
/** Remove all operations from OperationQueue.*/
void removeAllOperations();
/** Run the operations. */
2011-09-13 19:09:39 +08:00
virtual void runOperations();
2006-12-22 00:56:20 +08:00
2009-12-14 21:42:00 +08:00
typedef std::list< ref_ptr<Operation> > GraphicsOperationQueue;
2012-03-22 01:36:20 +08:00
2015-06-01 21:11:49 +08:00
/** Get the operations queue, note you must use the OperationsMutex when accessing the queue.*/
2009-12-14 21:42:00 +08:00
GraphicsOperationQueue& getOperationsQueue() { return _operations; }
2007-02-01 06:24:20 +08:00
/** Get the operations queue mutex.*/
2007-02-05 22:56:41 +08:00
OpenThreads::Mutex* getOperationsMutex() { return &_operationsMutex; }
2007-02-01 06:24:20 +08:00
2007-12-11 01:30:18 +08:00
/** Get the operations queue block used to mark an empty queue, if you end items into the empty queue you must release this block.*/
2007-02-24 00:31:34 +08:00
osg::RefBlock* getOperationsBlock() { return _operationsBlock.get(); }
2007-02-01 06:24:20 +08:00
/** Get the current operations that is being run.*/
2007-02-03 06:30:36 +08:00
Operation* getCurrentOperation() { return _currentOperation.get(); }
2007-02-01 06:24:20 +08:00
2005-07-21 16:43:24 +08:00
public:
2012-03-22 01:36:20 +08:00
2005-07-21 16:43:24 +08:00
/** Get the traits of the GraphicsContext.*/
inline const Traits* getTraits() const { return _traits.get(); }
2007-01-05 23:24:06 +08:00
/** Return whether a valid and usable GraphicsContext has been created.*/
2007-01-09 00:20:10 +08:00
virtual bool valid() const = 0;
2007-01-05 23:24:06 +08:00
2005-07-21 16:43:24 +08:00
/** Set the State object which tracks the current OpenGL state for this graphics context.*/
inline void setState(State* state) { _state = state; }
2012-03-22 01:36:20 +08:00
2005-07-21 16:43:24 +08:00
/** Get the State object which tracks the current OpenGL state for this graphics context.*/
inline State* getState() { return _state.get(); }
2012-03-22 01:36:20 +08:00
2005-07-21 16:43:24 +08:00
/** Get the const State object which tracks the current OpenGL state for this graphics context.*/
inline const State* getState() const { return _state.get(); }
2007-01-05 23:24:06 +08:00
/** Sets the clear color. */
inline void setClearColor(const Vec4& color) { _clearColor = color; }
/** Returns the clear color. */
inline const Vec4& getClearColor() const { return _clearColor; }
2012-03-22 01:36:20 +08:00
2007-01-05 23:24:06 +08:00
/** Set the clear mask used in glClear(..).
2011-09-12 20:04:46 +08:00
* 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. */
2007-01-05 23:24:06 +08:00
inline void setClearMask(GLbitfield mask) { _clearMask = mask; }
2005-08-16 21:29:07 +08:00
2007-01-05 23:24:06 +08:00
/** Get the clear mask.*/
inline GLbitfield getClearMask() const { return _clearMask; }
2012-03-22 01:36:20 +08:00
2007-01-05 23:24:06 +08:00
/** 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();
2012-03-22 01:36:20 +08:00
2009-03-12 23:18:51 +08:00
double getTimeSinceLastClear() const { return osg::Timer::instance()->delta_s(_lastClearTick, osg::Timer::instance()->tick()); }
2012-03-22 01:36:20 +08:00
2006-12-25 00:40:19 +08:00
2007-12-11 01:30:18 +08:00
/** Realize the GraphicsContext.*/
2005-08-20 16:59:03 +08:00
bool realize();
2005-07-21 16:43:24 +08:00
2005-08-30 22:41:08 +08:00
/** 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);
2005-08-20 16:59:03 +08:00
/** swap the front and back buffers.*/
void swapBuffers();
2007-12-11 01:30:18 +08:00
/** Return true if the graphics context has been realized and is ready to use.*/
2005-08-20 16:59:03 +08:00
inline bool isRealized() const { return isRealizedImplementation(); }
2005-07-22 03:27:19 +08:00
2005-08-16 21:29:07 +08:00
2005-08-19 04:17:51 +08:00
/** Make this graphics context current.
2012-03-22 01:36:20 +08:00
* Implemented by calling makeCurrentImplementation().
2007-01-09 03:29:59 +08:00
* Returns true on success. */
bool makeCurrent();
2012-03-22 01:36:20 +08:00
2005-08-19 04:17:51 +08:00
/** Make this graphics context current with specified read context.
2007-12-11 01:30:18 +08:00
* Implemented by calling makeContextCurrentImplementation().
2007-01-09 03:29:59 +08:00
* Returns true on success. */
bool makeContextCurrent(GraphicsContext* readContext);
2012-03-22 01:36:20 +08:00
2007-01-09 03:29:59 +08:00
/** Release the graphics context.
* Returns true on success. */
bool releaseContext();
2012-03-22 01:36:20 +08:00
2005-08-16 21:29:07 +08:00
/** Return true if the current thread has this OpenGL graphics context.*/
inline bool isCurrent() const { return _threadOfLastMakeCurrent == OpenThreads::Thread::CurrentThread(); }
2005-08-20 16:59:03 +08:00
/** Bind the graphics context to associated texture.*/
inline void bindPBufferToTexture(GLenum buffer) { bindPBufferToTextureImplementation(buffer); }
2005-08-16 21:29:07 +08:00
2005-08-19 04:17:51 +08:00
2005-07-21 16:43:24 +08:00
2005-08-20 16:59:03 +08:00
/** Create a graphics thread to the graphics context, so that the thread handles all OpenGL operations.*/
void createGraphicsThread();
2005-07-22 03:27:19 +08:00
2005-08-19 04:17:51 +08:00
/** Assign a graphics thread to the graphics context, so that the thread handles all OpenGL operations.*/
2007-07-12 23:54:45 +08:00
void setGraphicsThread(GraphicsThread* gt);
2005-08-19 04:17:51 +08:00
/** Get the graphics thread assigned the graphics context.*/
2007-07-12 23:54:45 +08:00
GraphicsThread* getGraphicsThread() { return _graphicsThread.get(); }
2005-08-19 04:17:51 +08:00
/** Get the const graphics thread assigned the graphics context.*/
2007-07-12 23:54:45 +08:00
const GraphicsThread* getGraphicsThread() const { return _graphicsThread.get(); }
2005-08-18 17:36:40 +08:00
2005-08-20 16:59:03 +08:00
2012-03-22 01:36:20 +08:00
/** Realize the GraphicsContext implementation,
2007-12-11 01:30:18 +08:00
* Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
2005-08-20 16:59:03 +08:00
virtual bool realizeImplementation() = 0;
2007-12-11 01:30:18 +08:00
/** 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. */
2005-08-20 16:59:03 +08:00
virtual bool isRealizedImplementation() const = 0;
/** Close the graphics context implementation.
2007-12-11 01:30:18 +08:00
* Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
2005-08-20 16:59:03 +08:00
virtual void closeImplementation() = 0;
/** Make this graphics context current implementation.
2007-12-11 01:30:18 +08:00
* Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
2007-01-09 03:29:59 +08:00
virtual bool makeCurrentImplementation() = 0;
2012-03-22 01:36:20 +08:00
2005-08-20 16:59:03 +08:00
/** Make this graphics context current with specified read context implementation.
2007-12-11 01:30:18 +08:00
* Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
2007-01-09 03:29:59 +08:00
virtual bool makeContextCurrentImplementation(GraphicsContext* readContext) = 0;
/** Release the graphics context implementation.*/
virtual bool releaseContextImplementation() = 0;
2005-08-20 16:59:03 +08:00
/** Pure virtual, Bind the graphics context to associated texture implementation.
2007-12-11 01:30:18 +08:00
* Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
2005-08-20 16:59:03 +08:00
virtual void bindPBufferToTextureImplementation(GLenum buffer) = 0;
2010-11-11 00:58:58 +08:00
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
2012-03-22 01:36:20 +08:00
* GraphicsContext::swapBuffersImplementation() */
2010-11-11 00:58:58 +08:00
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(); }
2015-04-08 02:01:12 +08:00
/** Convenience method for handling whether to call swapbuffers callback or the standard context swapBuffersImplementation.
2016-09-05 14:59:15 +08:00
* swapBuffersCallbackOrImplementation() is called by swapBuffers() and osg::SwapBuffersOperation, end users should normally
* call swapBuffers() rather than swapBuffersCallbackOrImplementation(). */
void swapBuffersCallbackOrImplementation()
2010-11-11 00:58:58 +08:00
{
if (_state.valid()) _state->frameCompleted();
if (_swapCallback.valid()) _swapCallback->swapBuffersImplementation(this);
else swapBuffersImplementation();
}
2005-08-20 16:59:03 +08:00
/** Swap the front and back buffers implementation.
2007-12-11 01:30:18 +08:00
* Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
2005-08-20 16:59:03 +08:00
virtual void swapBuffersImplementation() = 0;
2007-01-09 03:29:59 +08:00
2007-01-02 02:20:10 +08:00
/** 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. */
2007-01-09 00:20:10 +08:00
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;
};
2010-11-11 00:58:58 +08:00
/** Set the resized callback which overrides the GraphicsConext::realizedImplementation(), allow developers to provide custom behavior
2007-01-09 00:20:10 +08:00
* in response to a window being resized.*/
void setResizedCallback(ResizedCallback* rc) { _resizedCallback = rc; }
2010-11-11 00:58:58 +08:00
/** Get the resized callback which overrides the GraphicsConext::realizedImplementation().*/
2007-01-09 00:20:10 +08:00
ResizedCallback* getResizedCallback() { return _resizedCallback.get(); }
2010-11-11 00:58:58 +08:00
/** Get the const resized callback which overrides the GraphicsConext::realizedImplementation().*/
2007-01-09 00:20:10 +08:00
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);
2007-01-02 02:20:10 +08:00
typedef std::list< osg::Camera* > Cameras;
2015-06-01 21:11:49 +08:00
/** Get the list of cameras associated with this graphics context.*/
2007-01-02 02:20:10 +08:00
Cameras& getCameras() { return _cameras; }
2015-06-01 21:11:49 +08:00
/** Get the const list of cameras associated with this graphics context.*/
2007-01-02 02:20:10 +08:00
const Cameras& getCameras() const { return _cameras; }
2012-03-22 01:36:20 +08:00
2010-11-26 00:06:04 +08:00
/** 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; }
2012-03-22 01:36:20 +08:00
2010-11-26 00:06:04 +08:00
GLuint getDefaultFboId() const { return _defaultFboId; }
2007-01-02 02:20:10 +08:00
2007-06-12 23:32:04 +08:00
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"; }
2005-07-21 16:43:24 +08:00
protected:
2012-03-22 01:36:20 +08:00
2005-07-21 16:43:24 +08:00
GraphicsContext();
2007-02-03 06:30:36 +08:00
GraphicsContext(const GraphicsContext&, const osg::CopyOp&);
2005-07-21 16:43:24 +08:00
2005-07-25 22:28:22 +08:00
virtual ~GraphicsContext();
2007-02-03 06:30:36 +08:00
virtual Object* cloneType() const { return 0; }
virtual Object* clone(const CopyOp&) const { return 0; }
2007-07-06 02:33:20 +08:00
/** Register a GraphicsContext.*/
static void registerGraphicsContext(GraphicsContext* gc);
/** Unregister a GraphicsContext.*/
static void unregisterGraphicsContext(GraphicsContext* gc);
2007-01-02 02:20:10 +08:00
void addCamera(osg::Camera* camera);
void removeCamera(osg::Camera* camera);
2012-03-22 01:36:20 +08:00
2007-01-02 02:20:10 +08:00
Cameras _cameras;
2005-07-21 16:43:24 +08:00
2007-01-02 02:20:10 +08:00
friend class osg::Camera;
2005-08-20 16:59:03 +08:00
2012-03-22 01:36:20 +08:00
ref_ptr<Traits> _traits;
2005-07-21 16:43:24 +08:00
ref_ptr<State> _state;
2007-01-05 23:24:06 +08:00
Vec4 _clearColor;
GLbitfield _clearMask;
2005-07-21 16:43:24 +08:00
OpenThreads::Thread* _threadOfLastMakeCurrent;
2012-03-22 01:36:20 +08:00
2006-12-25 00:40:19 +08:00
OpenThreads::Mutex _operationsMutex;
2007-02-24 00:31:34 +08:00
osg::ref_ptr<osg::RefBlock> _operationsBlock;
2009-12-14 21:42:00 +08:00
GraphicsOperationQueue _operations;
2007-02-03 06:30:36 +08:00
osg::ref_ptr<Operation> _currentOperation;
2006-12-22 00:56:20 +08:00
2007-12-23 21:08:14 +08:00
ref_ptr<GraphicsThread> _graphicsThread;
2012-03-22 01:36:20 +08:00
2007-01-09 00:20:10 +08:00
ref_ptr<ResizedCallback> _resizedCallback;
2010-11-11 00:58:58 +08:00
ref_ptr<SwapCallback> _swapCallback;
2012-03-22 01:36:20 +08:00
2009-03-12 23:18:51 +08:00
Timer_t _lastClearTick;
2012-03-22 01:36:20 +08:00
2010-11-26 00:06:04 +08:00
GLuint _defaultFboId;
2005-07-21 16:43:24 +08:00
};
2014-10-21 22:46:12 +08:00
//#include <osg/GLExtensions>
class OSG_EXPORT SyncSwapBuffersCallback : public GraphicsContext::SwapCallback
{
public:
SyncSwapBuffersCallback();
virtual void swapBuffersImplementation(GraphicsContext* gc);
GLsync _previousSync;
};
2005-07-21 16:43:24 +08:00
2016-05-16 20:45:31 +08:00
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;
};
2018-08-04 05:57:45 +08:00
// Internal use only - compile on C90 compilers, which prohibit empty macro arguments.
#define _OSG_GRAPHICSCONTEXT_NO_ATTRIBS
#define REGISTER_WINDOWINGSYSTEMINTERFACE2(ext, classname, attribs) \
extern "C" attribs void graphicswindow_##ext(void) {} \
2018-05-21 20:10:40 +08:00
static osg::WindowingSystemInterfaceProxy<classname> s_proxy_##classname(#ext);
2018-08-04 05:57:45 +08:00
#define REGISTER_WINDOWINGSYSTEMINTERFACE(ext, classname) \
REGISTER_WINDOWINGSYSTEMINTERFACE2(ext, classname, _OSG_GRAPHICSCONTEXT_NO_ATTRIBS)
2005-07-21 16:43:24 +08:00
}
#endif