2005-07-21 16:43:24 +08:00
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 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>
2005-08-18 17:36:40 +08:00
2005-07-21 16:43:24 +08:00
#include <OpenThreads/Thread>
2005-08-18 17:36:40 +08:00
#include <list>
2005-07-21 16:43:24 +08:00
namespace osg {
2005-07-25 22:28:22 +08:00
/** Base class for providing Windowing API agnostic access to creating and managing graphics context.*/
2005-07-21 16:43:24 +08:00
class OSG_EXPORT GraphicsContext : public Referenced
{
public:
2005-07-25 22:28:22 +08:00
/** GraphicsContext Traits object provides the specification of what type of graphics context is required.*/
2005-07-21 16:43:24 +08:00
struct Traits : public osg::Referenced
{
Traits():
_displayNum(0),
_screenNum(0),
_x(0),
_y(0),
_width(0),
_height(0),
_windowDecoration(false),
_supportsResize(false),
_red(8),
_blue(8),
_green(8),
_alpha(0),
_depth(24),
_stencil(0),
_pbuffer(false),
_quadBufferStereo(false),
_doubleBuffer(false),
_target(0),
_level(0),
_face(0),
2005-07-26 00:12:24 +08:00
_mipMapGeneration(false),
2005-07-21 16:43:24 +08:00
_sharedContext() {}
// where graphic context is be hosted.
std::string _hostName;
unsigned int _displayNum;
unsigned int _screenNum;
// graphics context orginal and size
unsigned int _x;
unsigned int _y;
unsigned int _width;
unsigned int _height;
// window decoration and baviour
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;
// buffer configuration
bool _pbuffer;
bool _quadBufferStereo;
bool _doubleBuffer;
// render to texture
GLenum _target;
unsigned int _level;
unsigned int _face;
2005-07-26 00:12:24 +08:00
unsigned int _mipMapGeneration;
2005-07-21 16:43:24 +08:00
// shared context
GraphicsContext* _sharedContext;
};
2005-07-25 22:28:22 +08:00
/** Callback to be implemented to provide access to Windowing API's ability to create Windows/pbuffers.*/
2005-07-21 16:43:24 +08:00
struct CreateGraphicContexCallback : public osg::Referenced
{
virtual GraphicsContext* createGraphicsContext(Traits* traits) = 0;
virtual ~CreateGraphicContexCallback() {};
};
2005-07-25 22:28:22 +08:00
/** Set the create graphics context callback - this callback should be supplied by the windows toolkit. */
2005-07-21 16:43:24 +08:00
static void setCreateGraphicsContextCallback(CreateGraphicContexCallback* callback);
2005-07-25 22:28:22 +08:00
/** Get the create graphics context callback*/
2005-07-21 16:43:24 +08:00
static CreateGraphicContexCallback* getCreateGraphicsContextCallback();
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);
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();
/** Increment the usage count associate with a contextID. The usage count speficies 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);
2005-07-21 16:43:24 +08:00
public:
/** Get the traits of the GraphicsContext.*/
inline const Traits* getTraits() const { return _traits.get(); }
/** 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(); }
2005-08-16 21:29:07 +08:00
/** Realise the GraphicsContext.*/
virtual bool realize() = 0;
/** Return true if the graphics context has been realised and is ready to use.*/
virtual bool isRealized() const = 0;
2005-07-21 16:43:24 +08:00
2005-07-22 03:27:19 +08:00
/** Release the graphics context.*/
virtual void release() = 0;
2005-08-16 21:29:07 +08:00
2005-07-21 16:43:24 +08:00
/** Make this graphics context current.*/
virtual void makeCurrent() = 0;
/** Make this graphics context current with specified read context.*/
2005-07-22 03:27:19 +08:00
virtual void makeContextCurrent(GraphicsContext* readContext) = 0;
2005-07-21 16:43:24 +08:00
2005-08-18 17:36:40 +08:00
virtual void releaseContext() = 0;
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-07-21 16:43:24 +08:00
/** Bind the graphics context to associated texture.*/
virtual void bindPBufferToTexture(GLenum buffer) = 0;
2005-07-22 03:27:19 +08:00
/** swap the front and back buffers.*/
virtual void swapBuffers() = 0;
2005-08-18 17:36:40 +08:00
public:
struct GraphicsOperation : public Referenced
{
virtual void operator () (GraphicsContext& context) {}
};
class GraphicsThread : public Referenced, OpenThreads::Thread
{
public:
GraphicsThread() {}
typedef std::list< ref_ptr<GraphicsOperation> > OperationList;
void add(GraphicsOperation* operation);
virtual void run();
protected:
virtual ~GraphicsThread() {}
OpenThreads::Mutex _runListMutex;
OperationList _operations;
};
void setGraphicsThread(GraphicsThread* gt) { _graphicsThread = gt; }
GraphicsThread* getGraphicsThread() { return _graphicsThread.get(); }
const GraphicsThread* getGraphicsThread() const { return _graphicsThread.get(); }
2005-07-21 16:43:24 +08:00
protected:
GraphicsContext();
2005-07-25 22:28:22 +08:00
virtual ~GraphicsContext();
2005-07-21 16:43:24 +08:00
ref_ptr<Traits> _traits;
ref_ptr<State> _state;
OpenThreads::Thread* _threadOfLastMakeCurrent;
2005-08-18 17:36:40 +08:00
ref_ptr<GraphicsThread> _graphicsThread;
2005-07-21 16:43:24 +08:00
};
}
#endif