436 lines
18 KiB
C++
436 lines
18 KiB
C++
/* -*-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>
|
|
|
|
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():
|
|
displayNum(0),
|
|
screenNum(0) {}
|
|
|
|
ScreenIdentifier(unsigned int in_screenNum):
|
|
displayNum(0),
|
|
screenNum(in_screenNum) {}
|
|
|
|
ScreenIdentifier(const std::string& in_hostName,unsigned int in_displayNum, unsigned int in_screenNum):
|
|
hostName(in_hostName),
|
|
displayNum(in_displayNum),
|
|
screenNum(in_screenNum) {}
|
|
|
|
std::string displayName() const;
|
|
|
|
std::string hostName;
|
|
unsigned int displayNum;
|
|
unsigned int screenNum;
|
|
};
|
|
|
|
/** GraphicsContext Traits object provides the specification of what type of graphics context is required.*/
|
|
struct Traits : public osg::Referenced, public ScreenIdentifier
|
|
{
|
|
Traits():
|
|
x(0),
|
|
y(0),
|
|
width(0),
|
|
height(0),
|
|
windowDecoration(false),
|
|
supportsResize(true),
|
|
red(8),
|
|
blue(8),
|
|
green(8),
|
|
alpha(0),
|
|
depth(24),
|
|
stencil(0),
|
|
sampleBuffers(0),
|
|
samples(0),
|
|
pbuffer(false),
|
|
quadBufferStereo(false),
|
|
doubleBuffer(false),
|
|
target(0),
|
|
format(0),
|
|
level(0),
|
|
face(0),
|
|
mipMapGeneration(false),
|
|
vsync(true),
|
|
useMultiThreadedOpenGLEngine(false),
|
|
useCursor(true),
|
|
sharedContext(0),
|
|
setInheritedWindowPixelFormat(false) {}
|
|
|
|
// graphics context orginal and size
|
|
int x;
|
|
int y;
|
|
int width;
|
|
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;
|
|
|
|
// 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;
|
|
|
|
// use multithreaded OpenGL-engine (OS X only)
|
|
bool useMultiThreadedOpenGLEngine;
|
|
|
|
// enable cursor
|
|
bool useCursor;
|
|
|
|
// shared context
|
|
GraphicsContext* sharedContext;
|
|
|
|
osg::ref_ptr<osg::Referenced> inheritedWindowData;
|
|
|
|
// ask the GraphicsWindow implementation to set the pixel format of an inherited window
|
|
bool setInheritedWindowPixelFormat;
|
|
};
|
|
|
|
|
|
/** Callback to be implemented to provide access to Windowing API's ability to create Windows/pbuffers.*/
|
|
struct WindowingSystemInterface : public osg::Referenced
|
|
{
|
|
virtual unsigned int getNumScreens(const ScreenIdentifier& screenIdentifier = ScreenIdentifier()) = 0;
|
|
|
|
virtual void getScreenResolution(const ScreenIdentifier& screenIdentifier, unsigned int& width, unsigned int& height) = 0;
|
|
|
|
virtual bool setScreenResolution(const ScreenIdentifier& /*screenIdentifier*/, unsigned int /*width*/, unsigned int /*height*/) { return false; }
|
|
|
|
virtual bool setScreenRefreshRate(const ScreenIdentifier& /*screenIdentifier*/, double /*refreshRate*/) { return false; }
|
|
|
|
virtual GraphicsContext* createGraphicsContext(Traits* traits) = 0;
|
|
|
|
virtual ~WindowingSystemInterface() {};
|
|
};
|
|
|
|
|
|
/** 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);
|
|
|
|
/** Get the WindowingSystemInterface*/
|
|
static WindowingSystemInterface* getWindowingSystemInterface();
|
|
|
|
/** 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 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);
|
|
|
|
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. */
|
|
void runOperations();
|
|
|
|
typedef std::list< ref_ptr<Operation> > OperationQueue;
|
|
|
|
/** Get the operations queue, not you must use the OperationsMutex when accessing the queue.*/
|
|
OperationQueue& 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 queu 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 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT. */
|
|
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();
|
|
|
|
|
|
/** Realise 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 realised and is ready to use.*/
|
|
inline bool isRealized() const { return isRealizedImplementation(); }
|
|
|
|
|
|
/** Make this graphics context current.
|
|
* Implementated by calling makeCurrentImplementation().
|
|
* Returns true on success. */
|
|
bool makeCurrent();
|
|
|
|
/** Make this graphics context current with specified read context.
|
|
* Implementated 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::CurrentThread(); }
|
|
|
|
/** 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(OperationsThread* gt);
|
|
|
|
/** Get the graphics thread assigned the graphics context.*/
|
|
OperationsThread* getGraphicsThread() { return _graphicsThread.get(); }
|
|
|
|
/** Get the const graphics thread assigned the graphics context.*/
|
|
const OperationsThread* getGraphicsThread() const { return _graphicsThread.get(); }
|
|
|
|
|
|
/** 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 bool makeCurrentImplementation() = 0;
|
|
|
|
/** Make this graphics context current with specified read context implementation.
|
|
* Pure virtual - must be implemented by concrate 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 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;
|
|
|
|
|
|
|
|
/** 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 the list of cameras associated with this graphics context.*/
|
|
Cameras& getCameras() { return _cameras; }
|
|
|
|
/** Get the the const list of cameras associated with this graphics context.*/
|
|
const Cameras& getCameras() const { return _cameras; }
|
|
|
|
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;
|
|
|
|
OpenThreads::Thread* _threadOfLastMakeCurrent;
|
|
|
|
OpenThreads::Mutex _operationsMutex;
|
|
osg::ref_ptr<osg::RefBlock> _operationsBlock;
|
|
OperationQueue _operations;
|
|
osg::ref_ptr<Operation> _currentOperation;
|
|
|
|
ref_ptr<OperationsThread> _graphicsThread;
|
|
|
|
ref_ptr<ResizedCallback> _resizedCallback;
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
#endif
|