123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- /* -*-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 OSGVIEWER_VIEWERBASE
- #define OSGVIEWER_VIEWERBASE 1
- #include <osg/Stats>
- #include <osgUtil/UpdateVisitor>
- #include <osgUtil/IncrementalCompileOperation>
- #include <osgGA/EventVisitor>
- #include <osgGA/EventQueue>
- #include <osgViewer/Scene>
- #include <osgViewer/GraphicsWindow>
- namespace osgViewer {
- #define USE_REFERENCE_TIME DBL_MAX
- class View;
- /** ViewerBase is the view base class that is inherited by both Viewer and CompositeViewer.*/
- class OSGVIEWER_EXPORT ViewerBase : public virtual osg::Object
- {
- public:
- ViewerBase();
- ViewerBase(const ViewerBase& vb);
- /** Set the Stats object used to collect various frame related timing and scene graph stats.*/
- virtual void setViewerStats(osg::Stats* stats) = 0;
- /** Get the Viewers Stats object.*/
- virtual osg::Stats* getViewerStats() = 0;
- /** Get the Viewers Stats object.*/
- virtual const osg::Stats* getViewerStats() const = 0;
- /** read the viewer configuration from a configuration file.*/
- virtual bool readConfiguration(const std::string& filename) = 0;
- /** Get whether at least of one of this viewers windows are realized.*/
- virtual bool isRealized() const = 0;
- /** set up windows and associated threads.*/
- virtual void realize() = 0;
- /** Set whether the setUpThreading() method should call configureAffinity() to set up up the processor affinity of viewer threads.*/
- void setUseConfigureAffinity(bool flag) { _useConfigureAffinity = flag; }
- /** get whether the setUpThreading() method should call configureAffinity() to set up up the processor affinity of viewer threads.*/
- bool getUseConfigureAffinity() const { return _useConfigureAffinity; }
- /** analyse the viewer configuration and select an appropriate Affinity for main thread, and any graphics, camera threads and database pagers that are required.*/
- virtual void configureAffinity();
- /** Set the processor affinity of main thread.*/
- virtual void setProcessorAffinity(const OpenThreads::Affinity& affinity) { _affinity = affinity; }
- OpenThreads::Affinity& getProcessorAffinity() { return _affinity; }
- const OpenThreads::Affinity& getProcessorAffinity() const { return _affinity; }
- enum ThreadingModel
- {
- SingleThreaded,
- CullDrawThreadPerContext,
- ThreadPerContext = CullDrawThreadPerContext,
- DrawThreadPerContext,
- CullThreadPerCameraDrawThreadPerContext,
- ThreadPerCamera = CullThreadPerCameraDrawThreadPerContext,
- AutomaticSelection
- };
- /** Set the threading model the rendering traversals will use.*/
- virtual void setThreadingModel(ThreadingModel threadingModel);
- /** Get the threading model the rendering traversals will use.*/
- ThreadingModel getThreadingModel() const { return _threadingModel; }
- /** Let the viewer suggest the best threading model for the viewers camera/window setup and the hardware available.*/
- virtual ThreadingModel suggestBestThreadingModel();
- /** Set up the threading and processor affinity as per the viewers threading model.*/
- virtual void setUpThreading();
- /** Return true if viewer threads are running. */
- bool areThreadsRunning() const { return _threadsRunning; }
- /** Stop any threads being run by viewer.*/
- virtual void stopThreading();
- /** Start any threads required by the viewer.*/
- virtual void startThreading();
- enum BarrierPosition
- {
- BeforeSwapBuffers,
- AfterSwapBuffers
- };
- /** Set the position of the end barrier.
- * AfterSwapBuffers may result in slightly higher framerates, but may
- * lead to inconsistent swapping between different windows.
- * BeforeSwapBuffers may lead to slightly lower framerate, but improve consistency in timing of swap buffers,
- * especially important if you are likely to consistently break frame.*/
- void setEndBarrierPosition(BarrierPosition bp);
- /** Get the end barrier position.*/
- BarrierPosition getEndBarrierPosition() const { return _endBarrierPosition; }
- /** Set the end barrier operation. \c op may be one of GL_FLUSH, GL_FINISH,
- * or NO_OPERATION. NO_OPERATION is the default. Per BarrierOperation::operator()(),
- * a glFlush() command, glFinish() command, or no additional OpenGL command will be
- * issued before entering the end barrier. */
- void setEndBarrierOperation(osg::BarrierOperation::PreBlockOp op);
- /** Get the end barrier operation. */
- osg::BarrierOperation::PreBlockOp getEndBarrierOperation() const { return _endBarrierOperation; }
- /** Set the done flag to signal the viewer's work is done and should exit the frame loop.*/
- void setDone(bool done) { _done = done; }
- /** Return true if viewer's work is done and should exit the frame loop.*/
- bool done() const { return _done; }
- /** Set the EventVisitor. */
- void setEventVisitor(osgGA::EventVisitor* eventVisitor) { _eventVisitor = eventVisitor; }
- /** Get the EventVisitor. */
- osgGA::EventVisitor* getEventVisitor() { return _eventVisitor.get(); }
- /** Get the const EventVisitor. */
- const osgGA::EventVisitor* getEventVisitor() const { return _eventVisitor.get(); }
- /** Set the key event that the viewer checks on each frame to see if the viewer's done flag should be set to
- * signal end of viewers main loop.
- * Default value is Escape (osgGA::GUIEVentAdapter::KEY_Escape).
- * Setting to 0 switches off the feature.*/
- void setKeyEventSetsDone(int key) { _keyEventSetsDone = key; }
- /** get the key event that the viewer checks on each frame to see if the viewer's done flag.*/
- int getKeyEventSetsDone() const { return _keyEventSetsDone; }
- /** if the flag is true, the viewer set its done flag when a QUIT_APPLICATION is received, false disables this feature */
- void setQuitEventSetsDone(bool flag) { _quitEventSetsDone = flag; }
- /** @return true if the viewer respond to the QUIT_APPLICATION-event */
- bool getQuitEventSetsDone() const { return _quitEventSetsDone; }
- /** Hint to tell the renderingTraversals() method whether to call releaseContext() on the last
- * context that was made current by the thread calling renderingTraverals(). Note, when
- * running multi-threaded viewer no threads will be made current or release current.
- * Setting this hint to false can enable the frame loop to be lazy about calling makeCurrent
- * and releaseContext on each new frame, helping performance. However, if you frame loop
- * is managing multiple graphics context all from the main frame thread then this hint must
- * be left on, otherwise the wrong context could be left active, introducing errors in rendering.*/
- void setReleaseContextAtEndOfFrameHint(bool hint) { _releaseContextAtEndOfFrameHint = hint; }
- /** Hint to tell the renderingTraversals() method whether to call releaseContext().*/
- bool getReleaseContextAtEndOfFrameHint() const { return _releaseContextAtEndOfFrameHint; }
- /** Set the UpdateVisitor. */
- void setUpdateVisitor(osgUtil::UpdateVisitor* updateVisitor) { _updateVisitor = updateVisitor; }
- /** Get the UpdateVisitor. */
- osgUtil::UpdateVisitor* getUpdateVisitor() { return _updateVisitor.get(); }
- /** Get the const UpdateVisitor. */
- const osgUtil::UpdateVisitor* getUpdateVisitor() const { return _updateVisitor.get(); }
- /** Set the Update OperationQueue. */
- void setUpdateOperations(osg::OperationQueue* operations) { _updateOperations = operations; }
- /** Get the Update OperationQueue. */
- osg::OperationQueue* getUpdateOperations() { return _updateOperations.get(); }
- /** Get the const Update OperationQueue. */
- const osg::OperationQueue* getUpdateOperations() const { return _updateOperations.get(); }
- /** Add an update operation.*/
- void addUpdateOperation(osg::Operation* operation);
- /** Remove an update operation.*/
- void removeUpdateOperation(osg::Operation* operation);
- /** Set the graphics operation to call on realization of the viewers graphics windows.*/
- void setRealizeOperation(osg::Operation* op) { _realizeOperation = op; }
- /** Get the graphics operation to call on realization of the viewers graphics windows.*/
- osg::Operation* getRealizeOperation() { return _realizeOperation.get(); }
- /** Set the graphics operation to call before the viewers graphics contexts close.*/
- void setCleanUpOperation(osg::Operation* op) { _cleanUpOperation = op; }
- /** Get the graphics operation to call before the viewers graphics contexts close.*/
- osg::Operation* getCleanUpOperation() { return _cleanUpOperation.get(); }
- /** Set the incremental compile operation.
- * Used to manage the OpenGL object compilation and merging of subgraphs in a way that avoids overloading
- * the rendering of frame with too many new objects in one frame. */
- void setIncrementalCompileOperation(osgUtil::IncrementalCompileOperation* ico);
- /** Get the incremental compile operation. */
- osgUtil::IncrementalCompileOperation* getIncrementalCompileOperation() { return _incrementalCompileOperation.get(); }
- enum FrameScheme
- {
- ON_DEMAND,
- CONTINUOUS
- };
- void setRunFrameScheme(FrameScheme fs) { _runFrameScheme = fs; }
- FrameScheme getRunFrameScheme() const { return _runFrameScheme; }
- void setRunMaxFrameRate(double frameRate) { _runMaxFrameRate = frameRate; }
- double getRunMaxFrameRate() const { return _runMaxFrameRate; }
- /** Execute a main frame loop.
- * Equivalent to while (!viewer.done()) viewer.frame();
- * Also calls realize() if the viewer is not already realized,
- * and installs trackball manipulator if one is not already assigned.
- */
- virtual int run();
- /** check to see if the new frame is required, called by run(..) when FrameScheme is set to ON_DEMAND.*/
- virtual bool checkNeedToDoFrame() = 0;
- /** check to see if events have been received, return true if events are now available.*/
- virtual bool checkEvents() = 0;
- /** Render a complete new frame.
- * Calls advance(), eventTraversal(), updateTraversal(), renderingTraversals(). */
- virtual void frame(double simulationTime=USE_REFERENCE_TIME);
- virtual void advance(double simulationTime=USE_REFERENCE_TIME) = 0;
- virtual void eventTraversal() = 0;
- virtual void updateTraversal() = 0;
- virtual void renderingTraversals();
- typedef std::vector<osg::Camera*> Cameras;
- virtual void getCameras(Cameras& cameras, bool onlyActive=true) = 0;
- typedef std::vector<osg::GraphicsContext*> Contexts;
- virtual void getContexts(Contexts& contexts, bool onlyValid=true) = 0;
- typedef std::vector<osgViewer::GraphicsWindow*> Windows;
- virtual void getWindows(Windows& windows, bool onlyValid=true);
- typedef std::vector<OpenThreads::Thread*> Threads;
- virtual void getAllThreads(Threads& threads, bool onlyActive=true) = 0;
- typedef std::vector<osg::OperationThread*> OperationThreads;
- virtual void getOperationThreads(OperationThreads& threads, bool onlyActive=true) = 0;
- typedef std::vector<osgViewer::Scene*> Scenes;
- virtual void getScenes(Scenes& scenes, bool onlyValid=true) = 0;
- typedef std::vector<osgViewer::View*> Views;
- virtual void getViews(Views& views, bool onlyValid=true) = 0;
- /** Check to see if any windows are still open. If not, set viewer done to true. */
- void checkWindowStatus();
- /** Check to see if windows are still open using the list of contexts given as a parameter.
- * If no windows are open, stop rendering threads and set viewer done to true.
- * This function is more effective than checkWindowStatus() as it does not query
- * the context list and should be used whenever context list is already available in your code.*/
- void checkWindowStatus(const Contexts& contexts);
- virtual double elapsedTime() = 0;
- virtual osg::FrameStamp* getViewerFrameStamp() = 0;
- /** Get the keyboard and mouse usage of this viewer.*/
- virtual void getUsage(osg::ApplicationUsage& usage) const = 0;
- bool getRequestRedraw() const { return _requestRedraw; }
- bool getRequestContinousUpdate() const { return _requestContinousUpdate; }
- protected:
- void viewerBaseInit();
- friend class osgViewer::View;
- inline void makeCurrent(osg::GraphicsContext* gc)
- {
- if (_currentContext==gc) return;
- releaseContext();
- if (gc && gc->valid() && gc->makeCurrent()) _currentContext = gc;
- }
- inline void releaseContext()
- {
- if (_currentContext.valid() && _currentContext->valid())
- {
- _currentContext->releaseContext();
- }
- _currentContext = 0;
- }
- virtual void viewerInit() = 0;
- bool _firstFrame;
- bool _done;
- int _keyEventSetsDone;
- bool _quitEventSetsDone;
- bool _releaseContextAtEndOfFrameHint;
- bool _useConfigureAffinity;
- OpenThreads::Affinity _affinity;
- ThreadingModel _threadingModel;
- bool _threadsRunning;
- bool _requestRedraw;
- bool _requestContinousUpdate;
- FrameScheme _runFrameScheme;
- double _runMaxFrameRate;
- BarrierPosition _endBarrierPosition;
- osg::BarrierOperation::PreBlockOp _endBarrierOperation;
- osg::ref_ptr<osg::BarrierOperation> _startRenderingBarrier;
- osg::ref_ptr<osg::BarrierOperation> _endRenderingDispatchBarrier;
- osg::ref_ptr<osg::EndOfDynamicDrawBlock> _endDynamicDrawBlock;
- osg::ref_ptr<osgGA::EventVisitor> _eventVisitor;
- osg::ref_ptr<osg::OperationQueue> _updateOperations;
- osg::ref_ptr<osgUtil::UpdateVisitor> _updateVisitor;
- osg::ref_ptr<osg::Operation> _realizeOperation;
- osg::ref_ptr<osg::Operation> _cleanUpOperation;
- osg::ref_ptr<osgUtil::IncrementalCompileOperation> _incrementalCompileOperation;
- osg::observer_ptr<osg::GraphicsContext> _currentContext;
- private:
- // Define private copy constructor
- // otherwsie VS2015 will construct it's own which will call the private copy operator from osg::Object resulting in an compile error.
- ViewerBase& operator = (const ViewerBase&) { return *this; }
- };
- }
- #endif
|