root/OpenSceneGraph/trunk/include/osg/GraphicsContext @ 13130

Revision 13130, 22.7 kB (checked in by robert, 5 days ago)

Fixed comment

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSG_GRAPHICSCONTEXT
15#define OSG_GRAPHICSCONTEXT 1
16
17#include <osg/State>
18#include <osg/GraphicsThread>
19#include <osg/Timer>
20
21#include <vector>
22
23namespace osg {
24
25// forward declare osg::Camera
26class Camera;
27
28/** Base class for providing Windowing API agnostic access to creating and managing graphics context.*/
29class OSG_EXPORT GraphicsContext : public Object
30{
31    public:
32
33        struct OSG_EXPORT ScreenIdentifier
34        {
35            ScreenIdentifier();
36
37            ScreenIdentifier(int in_screenNum);
38
39            ScreenIdentifier(const std::string& in_hostName,int in_displayNum, int in_screenNum);
40
41            /** Return the display name in the form hostName::displayNum:screenNum. */
42            std::string displayName() const;
43
44            /** Read the DISPLAY environmental variable, and set the ScreenIdentifier accordingly.
45              * Note, if either of displayNum or screenNum are not defined then -1 is set respectively to
46              * signify that this parameter has not been set. When parameters are undefined one can call
47              * call setUndefinedScreenDetailsToDefaultScreen() after readDISPLAY() to ensure valid values. */
48            void readDISPLAY();
49
50            /** Set the screenIndentifier from the displayName string.
51              * Note, if either of displayNum or screenNum are not defined then -1 is set to
52              * signify that this parameter has not been set. When parameters are undefined one can call
53              * call setUndefinedScreenDetailsToDefaultScreen() after readDISPLAY() to ensure valid values. */
54            void setScreenIdentifier(const std::string& displayName);
55
56            /** Set any undefined displayNum or screenNum values (i.e. -1) to the default display & screen of 0 respectively.*/
57            void setUndefinedScreenDetailsToDefaultScreen()
58            {
59                if (displayNum<0) displayNum = 0;
60                if (screenNum<0) screenNum = 0;
61            }
62
63            std::string  hostName;
64            int displayNum;
65            int screenNum;
66        };
67
68        /** GraphicsContext Traits object provides the specification of what type of graphics context is required.*/
69        struct OSG_EXPORT Traits : public osg::Referenced, public ScreenIdentifier
70        {
71            Traits(DisplaySettings* ds=0);
72
73            // graphics context original and size
74            int x;
75            int y;
76            int width;
77            int height;
78
79            // window decoration and behaviour
80            std::string windowName;
81            bool        windowDecoration;
82            bool        supportsResize;
83
84            // buffer depths, 0 equals off.
85            unsigned int red;
86            unsigned int blue;
87            unsigned int green;
88            unsigned int alpha;
89            unsigned int depth;
90            unsigned int stencil;
91
92            // multi sample parameters
93            unsigned int sampleBuffers;
94            unsigned int samples;
95
96            // buffer configuration
97            bool pbuffer;
98            bool quadBufferStereo;
99            bool doubleBuffer;
100
101            // render to texture
102            GLenum          target;
103            GLenum          format;
104            unsigned int    level;
105            unsigned int    face;
106            unsigned int    mipMapGeneration;
107
108            // V-sync
109            bool            vsync;
110
111            // Swap Group
112            bool            swapGroupEnabled;
113            GLuint          swapGroup;
114            GLuint          swapBarrier;
115
116            // use multithreaded OpenGL-engine (OS X only)
117            bool            useMultiThreadedOpenGLEngine;
118
119            // enable cursor
120            bool            useCursor;
121
122            // settings used in set up of graphics context, only presently used by GL3 build of OSG.
123            std::string     glContextVersion;
124            unsigned int    glContextFlags;
125            unsigned int    glContextProfileMask;
126
127            /** return true if glContextVersion is set in the form major.minor, and assign the appropriate major and minor values to the associated parameters.*/
128            bool getContextVersion(unsigned int& major, unsigned int& minor) const;
129
130            // shared context
131            osg::observer_ptr<GraphicsContext> sharedContext;
132
133            osg::ref_ptr<osg::Referenced> inheritedWindowData;
134
135            // ask the GraphicsWindow implementation to set the pixel format of an inherited window
136            bool setInheritedWindowPixelFormat;
137
138            // X11 hint whether to override the window managers window size/position redirection
139            bool overrideRedirect;
140
141            DisplaySettings::SwapMethod swapMethod;
142        };
143
144        /** Simple resolution structure used by WindowingSystemInterface to get and set screen resolution.
145          * Note the '0' value stands for 'unset'. */
146        struct ScreenSettings {
147            ScreenSettings() :
148                width(0),
149                height(0),
150                refreshRate(0),
151                colorDepth(0)
152            {}
153            ScreenSettings(int width, int height, double refreshRate=0, unsigned int colorDepth=0) :
154                width(width),
155                height(height),
156                refreshRate(refreshRate),
157                colorDepth(colorDepth)
158            {}
159
160            int width;
161            int height;
162            double refreshRate;         ///< Screen refresh rate, in Hz.
163            unsigned int colorDepth;    ///< RGB(A) color buffer depth.
164        };
165
166        typedef std::vector<ScreenSettings> ScreenSettingsList;
167
168        /** Callback to be implemented to provide access to Windowing API's ability to create Windows/pbuffers.*/
169        struct WindowingSystemInterface : public osg::Referenced
170        {
171            virtual unsigned int getNumScreens(const ScreenIdentifier& screenIdentifier = ScreenIdentifier()) = 0;
172
173            virtual void getScreenSettings(const ScreenIdentifier& screenIdentifier, ScreenSettings & resolution) = 0;
174
175            virtual bool setScreenSettings(const ScreenIdentifier& /*screenIdentifier*/, const ScreenSettings & /*resolution*/) { return false; }
176
177            virtual void enumerateScreenSettings(const ScreenIdentifier& screenIdentifier, ScreenSettingsList & resolutionList) = 0;
178
179            virtual GraphicsContext* createGraphicsContext(Traits* traits) = 0;
180
181            virtual ~WindowingSystemInterface() {}
182
183
184            /** Gets screen resolution without using the ScreenResolution structure.
185              * \deprecated Provided only for backward compatibility. */
186            inline void getScreenResolution(const ScreenIdentifier& screenIdentifier, unsigned int& width, unsigned int& height)
187            {
188                ScreenSettings settings;
189                getScreenSettings(screenIdentifier, settings);
190                width = settings.width;
191                height = settings.height;
192            }
193
194            /** Sets screen resolution without using the ScreenSettings structure.
195              * \deprecated Provided only for backward compatibility. */
196            inline bool setScreenResolution(const ScreenIdentifier& screenIdentifier, unsigned int width, unsigned int height)
197            {
198                return setScreenSettings(screenIdentifier, ScreenSettings(width, height));
199            }
200
201            /** \deprecated Provided only for backward compatibility. */
202            inline bool setScreenRefreshRate(const ScreenIdentifier& screenIdentifier, double refreshRate)
203            {
204                ScreenSettings settings;
205                getScreenSettings(screenIdentifier, settings);
206                settings.refreshRate = refreshRate;
207                return setScreenSettings(screenIdentifier, settings);
208            }
209        };
210
211
212        /** Set the query the windowing system for screens and create graphics context - this functor should be supplied by the windows toolkit. */
213        static void setWindowingSystemInterface(WindowingSystemInterface* wsInterface);
214
215        /** Get the WindowingSystemInterface*/
216        static WindowingSystemInterface* getWindowingSystemInterface();
217
218        /** Create a graphics context for a specified set of traits.*/
219        static GraphicsContext* createGraphicsContext(Traits* traits);
220
221        /** Create a contextID for a new graphics context, this contextID is used to set up the osg::State associate with context.
222          * Automatically increments the usage count of the contextID to 1.*/
223        static unsigned int createNewContextID();
224
225        /** Get the current max ContextID.*/
226        static unsigned int getMaxContextID();
227
228        /** Increment the usage count associate with a contextID. The usage count specifies how many graphics contexts a specific contextID is shared between.*/
229        static void incrementContextIDUsageCount(unsigned int contextID);
230
231        /** Decrement the usage count associate with a contextID. Once the contextID goes to 0 the contextID is then free to be reused.*/
232        static void decrementContextIDUsageCount(unsigned int contextID);
233
234        typedef std::vector<GraphicsContext*> GraphicsContexts;
235
236        /** Get all the registered graphics contexts.*/
237        static GraphicsContexts getAllRegisteredGraphicsContexts();
238
239        /** Get all the registered graphics contexts associated with a specific contextID.*/
240        static GraphicsContexts getRegisteredGraphicsContexts(unsigned int contextID);
241
242        /** Get the GraphicsContext for doing background compilation for GraphicsContexts associated with specified contextID.*/
243        static void setCompileContext(unsigned int contextID, GraphicsContext* gc);
244
245        /** Get existing or create a new GraphicsContext to do background compilation for GraphicsContexts associated with specified contextID.*/
246        static  GraphicsContext* getOrCreateCompileContext(unsigned int contextID);
247
248        /** Get the GraphicsContext for doing background compilation for GraphicsContexts associated with specified contextID.*/
249        static GraphicsContext* getCompileContext(unsigned int contextID);
250
251    public:
252
253        /** Add operation to end of OperationQueue.*/
254        void add(Operation* operation);
255
256        /** Remove operation from OperationQueue.*/
257        void remove(Operation* operation);
258
259        /** Remove named operation from OperationQueue.*/
260        void remove(const std::string& name);
261
262        /** Remove all operations from OperationQueue.*/
263        void removeAllOperations();
264
265        /** Run the operations. */
266        virtual void runOperations();
267
268        typedef std::list< ref_ptr<Operation> > GraphicsOperationQueue;
269
270        /** Get the operations queue, not you must use the OperationsMutex when accessing the queue.*/
271        GraphicsOperationQueue& getOperationsQueue() { return _operations; }
272
273        /** Get the operations queue mutex.*/
274        OpenThreads::Mutex* getOperationsMutex() { return &_operationsMutex; }
275
276        /** Get the operations queue block used to mark an empty queue, if you end items into the empty queue you must release this block.*/
277        osg::RefBlock* getOperationsBlock() { return _operationsBlock.get(); }
278
279        /** Get the current operations that is being run.*/
280        Operation* getCurrentOperation() { return _currentOperation.get(); }
281
282
283    public:
284
285        /** Get the traits of the GraphicsContext.*/
286        inline const Traits* getTraits() const { return _traits.get(); }
287
288        /** Return whether a valid and usable GraphicsContext has been created.*/
289        virtual bool valid() const = 0;
290
291
292        /** Set the State object which tracks the current OpenGL state for this graphics context.*/
293        inline void setState(State* state) { _state = state; }
294
295        /** Get the State object which tracks the current OpenGL state for this graphics context.*/
296        inline State* getState() { return _state.get(); }
297
298        /** Get the const State object which tracks the current OpenGL state for this graphics context.*/
299        inline const State* getState() const { return _state.get(); }
300
301
302        /** Sets the clear color. */
303        inline void setClearColor(const Vec4& color) { _clearColor = color; }
304
305        /** Returns the clear color. */
306        inline const Vec4& getClearColor() const { return _clearColor; }
307
308        /** Set the clear mask used in glClear(..).
309          * Defaults to 0 - so no clear is done by default by the GraphicsContext, instead the Cameras attached to the GraphicsContext will do the clear.
310          * GraphicsContext::setClearMask() is useful for when the Camera Viewports don't cover the whole context, so the context will fill in the gaps. */
311        inline void setClearMask(GLbitfield mask) { _clearMask = mask; }
312
313        /** Get the clear mask.*/
314        inline GLbitfield getClearMask() const { return _clearMask; }
315
316        /** Do an OpenGL clear of the full graphics context/window.
317          * Note, must only be called from a thread with this context current.*/
318        virtual void clear();
319
320        double getTimeSinceLastClear() const { return osg::Timer::instance()->delta_s(_lastClearTick, osg::Timer::instance()->tick()); }
321
322
323        /** Realize the GraphicsContext.*/
324        bool realize();
325
326        /** close the graphics context.
327          * close(bool) stops any associated graphics threads, releases the contextID for the GraphicsContext then
328          * optional calls closeImplementation() to do the actual deletion of the graphics.  This call is made optional
329          * as there are times when the graphics context has already been deleted externally and only the OSG side
330          * of the its data need to be closed down. */
331        void close(bool callCloseImplementation=true);
332
333        /** swap the front and back buffers.*/
334        void swapBuffers();
335
336        /** Return true if the graphics context has been realized and is ready to use.*/
337        inline bool isRealized() const { return isRealizedImplementation(); }
338
339
340        /** Make this graphics context current.
341          * Implemented by calling makeCurrentImplementation().
342          * Returns true on success. */
343        bool makeCurrent();
344
345        /** Make this graphics context current with specified read context.
346          * Implemented by calling makeContextCurrentImplementation().
347          * Returns true on success. */
348        bool makeContextCurrent(GraphicsContext* readContext);
349
350        /** Release the graphics context.
351          * Returns true on success. */
352        bool releaseContext();
353
354        /** Return true if the current thread has this OpenGL graphics context.*/
355        inline bool isCurrent() const { return _threadOfLastMakeCurrent == OpenThreads::Thread::CurrentThread(); }
356
357        /** Bind the graphics context to associated texture.*/
358        inline void bindPBufferToTexture(GLenum buffer) { bindPBufferToTextureImplementation(buffer); }
359
360
361
362        /** Create a graphics thread to the graphics context, so that the thread handles all OpenGL operations.*/
363        void createGraphicsThread();
364
365        /** Assign a graphics thread to the graphics context, so that the thread handles all OpenGL operations.*/
366        void setGraphicsThread(GraphicsThread* gt);
367
368        /** Get the graphics thread assigned the graphics context.*/
369        GraphicsThread* getGraphicsThread() { return _graphicsThread.get(); }
370
371        /** Get the const graphics thread assigned the graphics context.*/
372        const GraphicsThread* getGraphicsThread() const { return _graphicsThread.get(); }
373
374
375        /** Realize the GraphicsContext implementation,
376          * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
377        virtual bool realizeImplementation() = 0;
378
379        /** Return true if the graphics context has been realized, and is ready to use, implementation.
380          * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
381        virtual bool isRealizedImplementation() const = 0;
382
383        /** Close the graphics context implementation.
384          * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
385        virtual void closeImplementation() = 0;
386
387        /** Make this graphics context current implementation.
388          * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
389        virtual bool makeCurrentImplementation() = 0;
390
391        /** Make this graphics context current with specified read context implementation.
392          * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
393        virtual bool makeContextCurrentImplementation(GraphicsContext* readContext) = 0;
394
395        /** Release the graphics context implementation.*/
396        virtual bool releaseContextImplementation() = 0;
397
398        /** Pure virtual, Bind the graphics context to associated texture implementation.
399          * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
400        virtual void bindPBufferToTextureImplementation(GLenum buffer) = 0;
401
402        struct SwapCallback : public osg::Referenced
403        {
404            virtual void swapBuffersImplementation(GraphicsContext* gc) = 0;
405        };
406        /** Set the swap callback which overrides the
407          * GraphicsContext::swapBuffersImplementation(), allowing
408          * developers to provide custom behavior for swap.
409          * The callback must call
410          * GraphicsContext::swapBuffersImplementation() */
411        void setSwapCallback(SwapCallback* rc) { _swapCallback = rc; }
412
413        /** Get the swap callback which overrides the GraphicsContext::swapBuffersImplementation().*/
414        SwapCallback* getSwapCallback() { return _swapCallback.get(); }
415
416        /** Get the const swap callback which overrides the GraphicsContext::swapBuffersImplementation().*/
417        const SwapCallback* getSwapCallback() const { return _swapCallback.get(); }
418
419        /** convinience method for handling whether to call swapbuffers callback or the standard context swapBuffersImplementation.
420          * swapBuffersCallbackOrImplemenation() is called by swapBuffers() and osg::SwapBuffersOperation, end users should normally
421          * call swapBuffers() rather than swapBuffersCallbackOrImplemenation(). */
422        void swapBuffersCallbackOrImplemenation()
423        {
424            if (_state.valid()) _state->frameCompleted();
425
426            if (_swapCallback.valid()) _swapCallback->swapBuffersImplementation(this);
427            else swapBuffersImplementation();
428        }
429
430        /** Swap the front and back buffers implementation.
431          * Pure virtual - must be implemented by concrete implementations of GraphicsContext. */
432        virtual void swapBuffersImplementation() = 0;
433
434
435
436        /** resized method should be called when the underlying window has been resized and the GraphicsWindow and associated Cameras must
437            be updated to keep in sync with the new size. */
438        void resized(int x, int y, int width, int height)
439        {
440            if (_resizedCallback.valid()) _resizedCallback->resizedImplementation(this, x, y, width, height);
441            else resizedImplementation(x, y, width, height);
442        }
443
444        struct ResizedCallback : public osg::Referenced
445        {
446            virtual void resizedImplementation(GraphicsContext* gc, int x, int y, int width, int height) = 0;
447        };
448
449        /** Set the resized callback which overrides the GraphicsConext::realizedImplementation(), allow developers to provide custom behavior
450          * in response to a window being resized.*/
451        void setResizedCallback(ResizedCallback* rc) { _resizedCallback = rc; }
452
453        /** Get the resized callback which overrides the GraphicsConext::realizedImplementation().*/
454        ResizedCallback* getResizedCallback() { return _resizedCallback.get(); }
455
456        /** Get the const resized callback which overrides the GraphicsConext::realizedImplementation().*/
457        const ResizedCallback* getResizedCallback() const { return _resizedCallback.get(); }
458
459        /** resized implementation, by default resizes the viewports and aspect ratios the cameras associated with the graphics Window. */
460        virtual void resizedImplementation(int x, int y, int width, int height);
461
462
463        typedef std::list< osg::Camera* > Cameras;
464
465        /** Get the the list of cameras associated with this graphics context.*/
466        Cameras& getCameras() { return _cameras; }
467
468        /** Get the the const list of cameras associated with this graphics context.*/
469        const Cameras& getCameras() const { return _cameras; }
470
471        /** set the default FBO-id, this id will be used when the rendering-backend is finished with RTT FBOs */
472        void setDefaultFboId(GLuint i) { _defaultFboId = i; }
473
474        GLuint getDefaultFboId() const { return _defaultFboId; }
475
476    public:
477
478        virtual bool isSameKindAs(const Object* object) const { return dynamic_cast<const GraphicsContext*>(object)!=0; }
479        virtual const char* libraryName() const { return "osg"; }
480        virtual const char* className() const { return "GraphicsContext"; }
481
482    protected:
483
484        GraphicsContext();
485        GraphicsContext(const GraphicsContext&, const osg::CopyOp&);
486
487        virtual ~GraphicsContext();
488
489        virtual Object* cloneType() const { return 0; }
490        virtual Object* clone(const CopyOp&) const { return 0; }
491
492        /** Register a GraphicsContext.*/
493        static void registerGraphicsContext(GraphicsContext* gc);
494
495        /** Unregister a GraphicsContext.*/
496        static void unregisterGraphicsContext(GraphicsContext* gc);
497
498
499        void addCamera(osg::Camera* camera);
500        void removeCamera(osg::Camera* camera);
501
502        Cameras _cameras;
503
504        friend class osg::Camera;
505
506        ref_ptr<Traits>         _traits;
507        ref_ptr<State>          _state;
508
509        Vec4                    _clearColor;
510        GLbitfield              _clearMask;
511
512        OpenThreads::Thread*    _threadOfLastMakeCurrent;
513
514        OpenThreads::Mutex                  _operationsMutex;
515        osg::ref_ptr<osg::RefBlock>         _operationsBlock;
516        GraphicsOperationQueue              _operations;
517        osg::ref_ptr<Operation>             _currentOperation;
518
519        ref_ptr<GraphicsThread>             _graphicsThread;
520
521        ref_ptr<ResizedCallback>            _resizedCallback;
522        ref_ptr<SwapCallback>               _swapCallback;
523
524        Timer_t                             _lastClearTick;
525
526        GLuint                              _defaultFboId;
527};
528
529
530}
531
532#endif
Note: See TracBrowser for help on using the browser.