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>
2005-08-18 17:36:40 +08:00
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:
2006-12-23 05:53:44 +08:00
struct OSG_EXPORT ScreenIdentifier
2006-12-18 04:49:01 +08:00
{
ScreenIdentifier():
2006-12-23 05:53:44 +08:00
displayNum(0),
screenNum(0) {}
2006-12-20 00:00:51 +08:00
2006-12-23 05:53:44 +08:00
ScreenIdentifier(unsigned int in_screenNum):
displayNum(0),
screenNum(in_screenNum) {}
2006-12-20 00:00:51 +08:00
2006-12-23 05:53:44 +08:00
ScreenIdentifier(const std::string& in_hostName,unsigned int in_displayNum, unsigned int in_screenNum):
hostName(in_hostName),
displayNum(in_displayNum),
screenNum(in_screenNum) {}
2006-12-18 04:49:01 +08:00
2006-12-23 05:53:44 +08:00
std::string displayName() const;
std::string hostName;
unsigned int displayNum;
unsigned int screenNum;
2006-12-18 04:49:01 +08:00
};
2005-07-25 22:28:22 +08:00
/** GraphicsContext Traits object provides the specification of what type of graphics context is required.*/
2006-12-18 04:49:01 +08:00
struct Traits : public osg::Referenced, public ScreenIdentifier
2005-07-21 16:43:24 +08:00
{
Traits():
2006-12-23 05:53:44 +08:00
x(0),
y(0),
width(0),
height(0),
windowDecoration(false),
supportsResize(false),
red(8),
blue(8),
green(8),
alpha(0),
depth(24),
stencil(0),
sampleBuffers(0),
samples(0),
pbuffer(false),
quadBufferStereo(false),
doubleBuffer(false),
target(0),
level(0),
face(0),
mipMapGeneration(false),
sharedContext(0) {}
2006-12-18 04:49:01 +08:00
2005-07-21 16:43:24 +08:00
// graphics context orginal and size
2006-12-23 05:53:44 +08:00
unsigned int x;
unsigned int y;
unsigned int width;
unsigned int height;
2005-07-21 16:43:24 +08:00
// window decoration and baviour
2006-12-23 05:53:44 +08:00
std::string windowName;
bool windowDecoration;
bool supportsResize;
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;
unsigned int level;
unsigned int face;
unsigned int mipMapGeneration;
2005-07-21 16:43:24 +08:00
// shared context
2006-12-23 05:53:44 +08:00
GraphicsContext* sharedContext;
2005-07-21 16:43:24 +08:00
};
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
{
2006-12-18 04:49:01 +08:00
virtual unsigned int getNumScreens(const ScreenIdentifier& screenIdentifier = ScreenIdentifier()) = 0;
virtual void getScreenResolution(const ScreenIdentifier& screenIdentifier, unsigned int& width, unsigned int& height) = 0;
2005-07-21 16:43:24 +08:00
virtual GraphicsContext* createGraphicsContext(Traits* traits) = 0;
2006-12-18 04:49:01 +08:00
virtual ~WindowingSystemInterface() {};
2005-07-21 16:43:24 +08:00
};
2006-12-18 04:49:01 +08:00
/** Set the querry the windowing system for screens and create graphics context - this functor should be supplied by the windows toolkit. */
static void setWindowingSystemInterface(WindowingSystemInterface* wsInterface);
2005-07-21 16:43:24 +08:00
2006-12-18 04:49:01 +08:00
/** Get the WindowingSystemInterface*/
static WindowingSystemInterface* getWindowingSystemInterface();
2005-07-21 16:43:24 +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);
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
2006-12-22 00:56:20 +08:00
public:
/** Add operation to end of OperationQueue.*/
2006-12-25 00:40:19 +08:00
void add(GraphicsOperation* operation);
2006-12-22 00:56:20 +08:00
/** Remove operation from OperationQueue.*/
2006-12-25 00:40:19 +08:00
void remove(GraphicsOperation* 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. */
void runOperations();
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
2006-12-25 00:40:19 +08:00
/** Return whether a valid and usable GraphicsContext has been created.*/
virtual bool valid() const { return false; }
2005-08-16 21:29:07 +08:00
/** Realise 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();
/** Return true if the graphics context has been realised and is ready to use.*/
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.
* Implementated by first aquiring a lock of the GraphicsContext mutex, and then doing a call to makeCurrentImplementation(). */
void makeCurrent();
2005-07-21 16:43:24 +08:00
2005-08-19 04:17:51 +08:00
/** Make this graphics context current with specified read context.
* Implementated by first aquiring a lock of the GraphicsContext mutex, and then doing a call to makeContextCurrentImplementation(). */
void makeContextCurrent(GraphicsContext* readContext);
2005-07-21 16:43:24 +08:00
2005-08-19 04:17:51 +08:00
/** Release the graphics context by unlocking the GraphicsContext mutex.*/
void releaseContext();
2005-08-18 17:36:40 +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.*/
2005-08-20 16:59:03 +08:00
void setGraphicsThread(GraphicsThread* gt);
2005-08-19 04:17:51 +08:00
/** Get the graphics thread assigned the graphics context.*/
2005-08-18 17:36:40 +08:00
GraphicsThread* getGraphicsThread() { return _graphicsThread.get(); }
2005-08-19 04:17:51 +08:00
/** Get the const graphics thread assigned the graphics context.*/
2005-08-18 17:36:40 +08:00
const GraphicsThread* getGraphicsThread() const { return _graphicsThread.get(); }
2005-08-20 16:59:03 +08:00
/** Realise the GraphicsContext implementation,
* Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
virtual bool realizeImplementation() = 0;
/** Return true if the graphics context has been realised, and is ready to use, implementation.
* Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
virtual bool isRealizedImplementation() const = 0;
/** Close the graphics context implementation.
* Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
virtual void closeImplementation() = 0;
/** Make this graphics context current implementation.
* Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
virtual void makeCurrentImplementation() = 0;
/** Make this graphics context current with specified read context implementation.
* Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
virtual void makeContextCurrentImplementation(GraphicsContext* readContext) = 0;
/** Pure virtual, Bind the graphics context to associated texture implementation.
* Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
virtual void bindPBufferToTextureImplementation(GLenum buffer) = 0;
/** Swap the front and back buffers implementation.
* Pure virtual - must be implemented by Concrate implementations of GraphicsContext. */
virtual void swapBuffersImplementation() = 0;
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
2005-08-20 16:59:03 +08:00
2005-07-21 16:43:24 +08:00
ref_ptr<Traits> _traits;
ref_ptr<State> _state;
2005-08-19 04:17:51 +08:00
OpenThreads::Mutex _mutex;
2005-07-21 16:43:24 +08:00
OpenThreads::Thread* _threadOfLastMakeCurrent;
2006-12-25 00:40:19 +08:00
typedef std::list< ref_ptr<GraphicsOperation> > OperationQueue;
OpenThreads::Mutex _operationsMutex;
osg::ref_ptr<osg::Block> _operationsBlock;
OperationQueue _operations;
osg::ref_ptr<GraphicsOperation> _currentOperation;
2006-12-22 00:56:20 +08:00
2006-12-25 00:40:19 +08:00
ref_ptr<GraphicsThread> _graphicsThread;
2005-08-18 17:36:40 +08:00
2005-07-21 16:43:24 +08:00
};
}
#endif