From def74d3471b4e6e757af44887597abac50c7a813 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 18 Sep 2006 20:54:48 +0000 Subject: [PATCH] Introduced new osg::View, and osg::RenderInfo classes into the core OSG to help handle scenes with multiple views with elements that need coordinating on a per view basis. Added beginings of new osgText::FadeText class (not functionality yet). --- Make/makedirdefs | 1 + VisualStudio/osg/osg.dsp | 12 + VisualStudio/osgText/osgText.dsp | 8 + examples/osgfadetext/GNUmakefile | 18 ++ examples/osgfadetext/GNUmakefile.inst | 14 ++ examples/osgfadetext/osgfadetext.cpp | 220 +++++++++++++++++ examples/osgforest/osgforest.cpp | 4 +- .../osgshaderterrain/osgshaderterrain.cpp | 4 +- include/osg/BlendColor | 5 +- include/osg/CameraNode | 15 ++ include/osg/Drawable | 37 +-- include/osg/NodeVisitor | 2 + include/osg/RenderInfo | 70 ++++++ include/osg/State | 3 +- include/osg/StateAttribute | 6 +- include/osg/View | 174 +++++++++++++ include/osgParticle/PrecipitationEffect | 2 +- include/osgProducer/OsgCameraGroup | 3 + include/osgText/FadeText | 51 ++++ include/osgText/Text | 15 +- include/osgUtil/CullVisitor | 12 +- include/osgUtil/RenderBin | 6 +- include/osgUtil/RenderLeaf | 2 +- include/osgUtil/RenderStage | 14 +- include/osgUtil/SceneView | 18 +- src/osg/BlendColor.cpp | 2 +- src/osg/CameraNode.cpp | 2 + src/osg/GNUmakefile | 1 + src/osg/StateAttribute.cpp | 1 + src/osg/View.cpp | 221 +++++++++++++++++ src/osgParticle/PrecipitationEffect.cpp | 8 +- src/osgProducer/OsgCameraGroup.cpp | 8 + src/osgProducer/ViewerEventHandler.cpp | 28 +-- src/osgText/FadeText.cpp | 233 ++++++++++++++++++ src/osgText/GNUmakefile | 1 + src/osgText/Text.cpp | 47 ++-- src/osgUtil/CullVisitor.cpp | 2 +- src/osgUtil/RenderBin.cpp | 18 +- src/osgUtil/RenderLeaf.cpp | 8 +- src/osgUtil/RenderStage.cpp | 55 +++-- src/osgUtil/SceneView.cpp | 146 +++++------ 41 files changed, 1303 insertions(+), 194 deletions(-) create mode 100644 examples/osgfadetext/GNUmakefile create mode 100644 examples/osgfadetext/GNUmakefile.inst create mode 100644 examples/osgfadetext/osgfadetext.cpp create mode 100644 include/osg/RenderInfo create mode 100644 include/osg/View create mode 100644 include/osgText/FadeText create mode 100644 src/osg/View.cpp create mode 100644 src/osgText/FadeText.cpp diff --git a/Make/makedirdefs b/Make/makedirdefs index bc694e085..d8b9e2b88 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -277,6 +277,7 @@ ifeq ($(PRODUCER_INSTALLED),yes) EXAMPLE_DIRS += osgphotoalbum EXAMPLE_DIRS += osgbluemarble EXAMPLE_DIRS += osgsimulation + EXAMPLE_DIRS += osgfadetext endif endif diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index 1a4818208..409ced31a 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -608,6 +608,10 @@ SOURCE=..\..\src\osg\VertexProgram.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osg\View.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osg\Viewport.cpp # End Source File # End Group @@ -996,6 +1000,10 @@ SOURCE=..\..\Include\Osg\Referenced # End Source File # Begin Source File +SOURCE=..\..\Include\Osg\RenderInfo +# End Source File +# Begin Source File + SOURCE=..\..\Include\Osg\Scissor # End Source File # Begin Source File @@ -1184,6 +1192,10 @@ SOURCE=..\..\Include\Osg\VertexProgram # End Source File # Begin Source File +SOURCE=..\..\include\osg\View +# End Source File +# Begin Source File + SOURCE=..\..\include\osg\Viewport # End Source File # End Group diff --git a/VisualStudio/osgText/osgText.dsp b/VisualStudio/osgText/osgText.dsp index dc4074c8b..f0effef2a 100644 --- a/VisualStudio/osgText/osgText.dsp +++ b/VisualStudio/osgText/osgText.dsp @@ -171,6 +171,10 @@ SOURCE=..\..\src\osgText\Text.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osgText\FadeText.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osgText\Version.cpp # End Source File # End Group @@ -195,6 +199,10 @@ SOURCE=..\..\include\osgText\Text # End Source File # Begin Source File +SOURCE=..\..\include\osgText\FadeText +# End Source File +# Begin Source File + SOURCE=..\..\include\osgText\Version # End Source File # End Group diff --git a/examples/osgfadetext/GNUmakefile b/examples/osgfadetext/GNUmakefile new file mode 100644 index 000000000..a7d9dca67 --- /dev/null +++ b/examples/osgfadetext/GNUmakefile @@ -0,0 +1,18 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgfadetext.cpp\ + +LIBS += -losgTerrain -losgProducer -lProducer -losgSim -losgText -losgGA -losgDB -losgUtil -losg $(GDAL_LIBS) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgfadetext + +INC += $(X_INC) + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgfadetext/GNUmakefile.inst b/examples/osgfadetext/GNUmakefile.inst new file mode 100644 index 000000000..8ccb6f31b --- /dev/null +++ b/examples/osgfadetext/GNUmakefile.inst @@ -0,0 +1,14 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgfadetext.cpp\ + +LIBS += -losgProducer -lProducer -losgDB -losgSim -losgText -losgUtil -losg $(GDAL_LIBS) $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgfadetext + +INC += $(PRODUCER_INCLUDE_DIR) $(X_INC) +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgfadetext/osgfadetext.cpp b/examples/osgfadetext/osgfadetext.cpp new file mode 100644 index 000000000..06874fde7 --- /dev/null +++ b/examples/osgfadetext/osgfadetext.cpp @@ -0,0 +1,220 @@ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include +#include + +#include + +class GraphicsContext { + public: + GraphicsContext() + { + rs = new Producer::RenderSurface; + rs->setWindowRectangle(0,0,1,1); + rs->useBorder(false); + rs->useConfigEventThread(false); + rs->realize(); + } + + virtual ~GraphicsContext() + { + } + + private: + Producer::ref_ptr rs; +}; + +osg::Node* createEarth() +{ + osg::ref_ptr scene; + + { + std::string filename = osgDB::findDataFile("Images/land_shallow_topo_2048.jpg"); + + // make osgTerrain::DataSet quieter.. + osgTerrain::DataSet::setNotifyOffset(1); + + osg::ref_ptr dataSet = new osgTerrain::DataSet; + + // register the source imagery + { + osgTerrain::DataSet::Source* source = new osgTerrain::DataSet::Source(osgTerrain::DataSet::Source::IMAGE, filename); + + source->setCoordinateSystemPolicy(osgTerrain::DataSet::Source::PREFER_CONFIG_SETTINGS); + source->setCoordinateSystem(osgTerrain::DataSet::coordinateSystemStringToWTK("WGS84")); + + source->setGeoTransformPolicy(osgTerrain::DataSet::Source::PREFER_CONFIG_SETTINGS_BUT_SCALE_BY_FILE_RESOLUTION); + source->setGeoTransformFromRange(-180.0, 180.0, -90.0, 90.0); + + dataSet->addSource(source); + } + + // set up destination database paramters. + dataSet->setDatabaseType(osgTerrain::DataSet::LOD_DATABASE); + dataSet->setConvertFromGeographicToGeocentric(true); + dataSet->setDestinationName("test.osg"); + + // load the source data and record sizes. + dataSet->loadSources(); + + GraphicsContext context; + dataSet->createDestination(30); + + if (dataSet->getDatabaseType()==osgTerrain::DataSet::LOD_DATABASE) dataSet->buildDestination(); + else dataSet->writeDestination(); + + scene = dataSet->getDestinationRootNode(); + + // now we must get rid of all the old OpenGL objects before we start using the scene graph again + // otherwise it'll end up in an inconsistent state. + scene->releaseGLObjects(dataSet->getState()); + osg::Texture::flushAllDeletedTextureObjects(0); + osg::Drawable::flushAllDeletedDisplayLists(0); + } + + return scene.release(); + +} + +osg::Node* createFadeText(osg::EllipsoidModel* ellipsoid) +{ + osg::Group* group = new osg::Group; + + osg::Vec3 position; + + { + osg::Geode* geode = new osg::Geode; + osgText::Text* text = new osgText::Text; + + text->setText("This is a test"); + text->setFont("fonts/arial.ttf"); + text->setPosition(position); + text->setCharacterSize(300000.0f); + text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT); + text->setAutoRotateToScreen(true); + + geode->addDrawable(text); + group->addChild(geode); + } + + position.z() += 300000.0f; + + { + osg::Geode* geode = new osg::Geode; + osgText::FadeText* text = new osgText::FadeText; + + text->setText("This is a test"); + text->setFont("fonts/arial.ttf"); + text->setPosition(position); + text->setCharacterSize(300000.0f); + text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT); + text->setAutoRotateToScreen(true); + + geode->addDrawable(text); + group->addChild(geode); + } + + return group; +} + + +int main(int argc, char **argv) +{ + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + // set up the usage document, in case we need to print out how to use this program. + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of node tracker."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + + + // construct the viewer. + osgProducer::Viewer viewer(arguments); + + // set up the value with sensible default event handlers. + viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); + + viewer.getCullSettings().setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES); + viewer.getCullSettings().setNearFarRatio(0.00001f); + + // get details on keyboard and mouse bindings used by the viewer. + viewer.getUsage(*arguments.getApplicationUsage()); + + + // if user request help write it out to cout. + if (arguments.read("-h") || arguments.read("--help")) + { + arguments.getApplicationUsage()->write(std::cout); + return 1; + } + + // any option left unread are converted into errors to write out later. + arguments.reportRemainingOptionsAsUnrecognized(); + + // report any errors if they have occured when parsing the program aguments. + if (arguments.errors()) + { + arguments.writeErrorMessages(std::cout); + return 1; + } + + // read the scene from the list of file specified commandline args. + osg::ref_ptr root = createEarth(); + + if (!root) return 0; + + // add a viewport to the viewer and attach the scene graph. + viewer.setSceneData(root.get()); + + osg::CoordinateSystemNode* csn = dynamic_cast(root.get()); + if (csn) + { + // add fade text around the globe + csn->addChild(createFadeText(csn->getEllipsoidModel())); + } + + + // create the windows and run the threads. + viewer.realize(); + + while( !viewer.done() ) + { + // wait for all cull and draw threads to complete. + viewer.sync(); + + // update the scene by traversing it with the the update visitor which will + // call all node update callbacks and animations. + viewer.update(); + + // fire off the cull and draw traversals of the scene. + viewer.frame(); + + } + + // wait for all cull and draw threads to complete. + viewer.sync(); + + // run a clean up frame to delete all OpenGL objects. + viewer.cleanup_frame(); + + // wait for all the clean up frame to complete. + viewer.sync(); + + return 0; +} diff --git a/examples/osgforest/osgforest.cpp b/examples/osgforest/osgforest.cpp index e46a47c89..8eb4c90bc 100644 --- a/examples/osgforest/osgforest.cpp +++ b/examples/osgforest/osgforest.cpp @@ -771,14 +771,14 @@ class ShaderGeometry : public osg::Drawable typedef std::vector PositionSizeList; - virtual void drawImplementation(osg::State& state) const + virtual void drawImplementation(osg::RenderInfo& renderInfo) const { for(PositionSizeList::const_iterator itr = _trees.begin(); itr != _trees.end(); ++itr) { glColor4fv(itr->ptr()); - _geometry->draw(state); + _geometry->draw(renderInfo); } } diff --git a/examples/osgshaderterrain/osgshaderterrain.cpp b/examples/osgshaderterrain/osgshaderterrain.cpp index 6a20aff43..829dbe4c5 100644 --- a/examples/osgshaderterrain/osgshaderterrain.cpp +++ b/examples/osgshaderterrain/osgshaderterrain.cpp @@ -364,14 +364,14 @@ class ShaderGeometry : public osg::Drawable typedef std::vector PositionSizeList; - virtual void drawImplementation(osg::State& state) const + virtual void drawImplementation(osg::RenderInfo& renderInfo) const { for(PositionSizeList::const_iterator itr = _trees.begin(); itr != _trees.end(); ++itr) { glColor4fv(itr->ptr()); - _geometry->draw(state); + _geometry->draw(renderInfo); } } diff --git a/include/osg/BlendColor b/include/osg/BlendColor index b849a566b..ccaabc937 100644 --- a/include/osg/BlendColor +++ b/include/osg/BlendColor @@ -59,7 +59,10 @@ class OSG_EXPORT BlendColor : public StateAttribute } void setConstantColor(const osg::Vec4& color) { _constantColor = color; } - inline osg::Vec4 getConstantColor() const { return _constantColor; } + + inline osg::Vec4& getConstantColor() { return _constantColor; } + + inline const osg::Vec4& getConstantColor() const { return _constantColor; } virtual void apply(State& state) const; diff --git a/include/osg/CameraNode b/include/osg/CameraNode index 3be47ef01..74d539807 100644 --- a/include/osg/CameraNode +++ b/include/osg/CameraNode @@ -26,6 +26,9 @@ namespace osg { +// forward declare View to allow CameraNode to point back to the View that its within +class View; + /** CameraNode - is a subclass of Transform which represents encapsulates the settings of a Camera. */ class OSG_EXPORT CameraNode : public Transform, public CullSettings @@ -40,6 +43,15 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings META_Node(osg, CameraNode); + /** Set the View that this Camera is part of. */ + void setView(View* view) { _view = view; } + + /** Get the View that this Camera is part of. */ + View* getView() { return _view; } + + /** Get the const View that this Camera is part of. */ + const View* getView() const { return _view; } + /** Sets the clear color. */ inline void setClearColor(const Vec4& color) { _clearColor = color; } @@ -359,6 +371,9 @@ class OSG_EXPORT CameraNode : public Transform, public CullSettings mutable OpenThreads::Mutex _dataChangeMutex; + + View* _view; + Vec4 _clearColor; GLbitfield _clearMask; ref_ptr _colorMask; diff --git a/include/osg/Drawable b/include/osg/Drawable index beffd1e82..deeddd0d0 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -18,7 +18,7 @@ #include #include #include -#include +#include #ifndef GL_NV_occlusion_query @@ -271,7 +271,7 @@ class OSG_EXPORT Drawable : public Object * \c virtual). Subclasses should override * \c drawImplementation() instead. */ - inline void draw(State& state) const; + inline void draw(RenderInfo& renderInfo) const; /** Immediately compile this \c Drawable into an OpenGL Display List. * @note Operation is ignored if \c _useDisplayList is \c false. @@ -341,8 +341,11 @@ class OSG_EXPORT Drawable : public Object META_Object(osg,CullCallback); - /** do customized cull code, return true if drawable should be culled.*/ + /** deprecated.*/ virtual bool cull(osg::NodeVisitor*, osg::Drawable*, osg::State*) const { return false; } + + /** do customized cull code, return true if drawable should be culled.*/ + virtual bool cull(osg::NodeVisitor* nv, osg::Drawable* drawable, osg::RenderInfo* renderInfo) const { return cull(nv, drawable, renderInfo? renderInfo->getState():0); } }; /** Set the CullCallback which allows users to customize the culling of Drawable during the cull traversal.*/ @@ -370,8 +373,11 @@ class OSG_EXPORT Drawable : public Object META_Object(osg,DrawCallback); - /** do customized draw code.*/ + /** Deprecated.*/ virtual void drawImplementation(osg::State&,const osg::Drawable*) const {} + + /** do customized draw code.*/ + virtual void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const { drawImplementation(*renderInfo.getState(), drawable); } }; /** Set the DrawCallback which allows users to attach customize the drawing of existing Drawable object.*/ @@ -383,14 +389,15 @@ class OSG_EXPORT Drawable : public Object /** Get the const DrawCallback.*/ const DrawCallback* getDrawCallback() const { return _drawCallback.get(); } - + /** Deprecated. */ + virtual void drawImplementation(State&) const {} /** drawImplementation(State&) is a pure virtual method for the actual implementation of OpenGL drawing calls, such as vertex arrays and primitives, that * must be implemented in concrete subclasses of the Drawable base class, examples include osg::Geometry and osg::ShapeDrawable. * drawImplementation(State&) is called from the draw(State&) method, with the draw method handling management of OpenGL display lists, * and drawImplementation(State&) handling the actuall drawing itself. * @param state The osg::State object that encapulates the current OpenGL state for the current graphics context. */ - virtual void drawImplementation(State& state) const = 0; + virtual void drawImplementation(RenderInfo& renderInfo) const { drawImplementation(*renderInfo.getState()); } /** Return a OpenGL display list handle a newly generated or reused from display list cache. */ @@ -779,13 +786,13 @@ class OSG_EXPORT Drawable : public Object ref_ptr _drawCallback; }; -inline void Drawable::draw(State& state) const +inline void Drawable::draw(RenderInfo& renderInfo) const { - if (_useDisplayList && !(_supportsVertexBufferObjects && _useVertexBufferObjects && state.isVertexBufferObjectSupported())) + if (_useDisplayList && !(_supportsVertexBufferObjects && _useVertexBufferObjects && renderInfo.getState()->isVertexBufferObjectSupported())) { // get the contextID (user defined ID of 0 upwards) for the // current OpenGL context. - unsigned int contextID = state.getContextID(); + unsigned int contextID = renderInfo.getContextID(); // get the globj for the current contextID. GLuint& globj = _globjList[contextID]; @@ -801,9 +808,9 @@ inline void Drawable::draw(State& state) const globj = generateDisplayList(contextID, getGLObjectSizeHint()); glNewList( globj, GL_COMPILE ); if (_drawCallback.valid()) - _drawCallback->drawImplementation(state,this); + _drawCallback->drawImplementation(renderInfo,this); else - drawImplementation(state); + drawImplementation(renderInfo); glEndList(); glCallList( globj); @@ -811,9 +818,9 @@ inline void Drawable::draw(State& state) const globj = generateDisplayList(contextID, getGLObjectSizeHint()); glNewList( globj, GL_COMPILE_AND_EXECUTE ); if (_drawCallback.valid()) - _drawCallback->drawImplementation(state,this); + _drawCallback->drawImplementation(renderInfo,this); else - drawImplementation(state); + drawImplementation(renderInfo); glEndList(); #endif } @@ -824,9 +831,9 @@ inline void Drawable::draw(State& state) const // draw object as nature intended.. if (_drawCallback.valid()) - _drawCallback->drawImplementation(state,this); + _drawCallback->drawImplementation(renderInfo,this); else - drawImplementation(state); + drawImplementation(renderInfo); } diff --git a/include/osg/NodeVisitor b/include/osg/NodeVisitor index 70dada553..7af517e72 100644 --- a/include/osg/NodeVisitor +++ b/include/osg/NodeVisitor @@ -40,6 +40,7 @@ class TexGenNode; class Transform; class CameraNode; class CameraView; +class View; /** Visitor for type safe operations on osg::Nodes. Based on GOF's Visitor pattern. The NodeVisitor @@ -235,6 +236,7 @@ class OSG_EXPORT NodeVisitor : public virtual Referenced virtual void apply(LightSource& node) { apply((Group&)node); } virtual void apply(Transform& node) { apply((Group&)node); } + virtual void apply(View& node) { apply((Transform&)node); } virtual void apply(CameraNode& node) { apply((Transform&)node); } virtual void apply(CameraView& node) { apply((Transform&)node); } virtual void apply(MatrixTransform& node) { apply((Transform&)node); } diff --git a/include/osg/RenderInfo b/include/osg/RenderInfo new file mode 100644 index 000000000..c8b35bbdf --- /dev/null +++ b/include/osg/RenderInfo @@ -0,0 +1,70 @@ +/* -*-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_RENDERINFO +#define OSG_RENDERINFO 1 + +#include +#include +#include + +namespace osg { + +class RenderInfo +{ +public: + + RenderInfo(): + _view(0) {} + + RenderInfo(const RenderInfo& rhs): + _state(rhs._state), + _view(rhs._view), + _userData(rhs._userData) {} + + RenderInfo(State* state, View* view): + _state(state), + _view(view) {} + + RenderInfo& operator = (const RenderInfo& rhs) + { + _state = rhs._state; + _view = rhs._view; + _userData = rhs._userData; + return *this; + } + + unsigned int getContextID() const { return _state.valid() ? _state->getContextID() : 0; } + + void setState(State* state) { _state = state; } + State* getState() { return _state.get(); } + const State* getState() const { return _state.get(); } + + void setView(View* view) { _view = view; } + View* getView() { return _view.get(); } + const View* getView() const { return _view.get(); } + + void setUserData(Referenced* userData) { _userData = userData; } + Referenced* getUserData() { return _userData.get(); } + const Referenced* getUserData() const { return _userData.get(); } + +protected: + + ref_ptr _state; + observer_ptr _view; + ref_ptr _userData; +}; + +} + +#endif diff --git a/include/osg/State b/include/osg/State index f491e4bd4..ac1796016 100644 --- a/include/osg/State +++ b/include/osg/State @@ -64,7 +64,7 @@ namespace osg { } -// forward decalr GraphicsContext +// forward declare GraphicsContext, View and State class GraphicsContext; /** Encapsulates the current applied OpenGL modes, attributes and vertex arrays settings, @@ -1531,6 +1531,7 @@ inline void State::applyUniformMap(UniformMap& uniformMap) } } + } #endif diff --git a/include/osg/StateAttribute b/include/osg/StateAttribute index 4d3b5581c..2260292e2 100644 --- a/include/osg/StateAttribute +++ b/include/osg/StateAttribute @@ -306,12 +306,12 @@ class OSG_EXPORT StateAttribute : public Object /** apply the OpenGL state attributes. - * The global state for the current OpenGL context is passed + * The render info for the current OpenGL context is passed * in to allow the StateAttribute to obtain details on the * the current context and state. */ - virtual void apply(State&) const = 0; - + virtual void apply(State&) const {} + /** default to nothing to compile - all state is applied immediately. */ virtual void compileGLObjects(State&) const {} diff --git a/include/osg/View b/include/osg/View new file mode 100644 index 000000000..c56b2bf88 --- /dev/null +++ b/include/osg/View @@ -0,0 +1,174 @@ +/* -*-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_VIEW +#define OSG_VIEW 1 + +#include + +#include + +namespace osg { + +/** View - is a subclass of Transform which encompasses all the cameras that combine to make up a single view of the scene. +*/ +class OSG_EXPORT View : public osg::Transform, public CullSettings +{ + public : + + + View(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + View(const View&,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + META_Node(osg, View); + + + /** Set the projection matrix. Can be thought of as setting the lens of a camera. */ + inline void setProjectionMatrix(const osg::Matrixf& matrix) { _projectionMatrix.set(matrix); updateCameras(); } + + /** Set the projection matrix. Can be thought of as setting the lens of a camera. */ + inline void setProjectionMatrix(const osg::Matrixd& matrix) { _projectionMatrix.set(matrix); updateCameras(); } + + /** Set to an orthographic projection. See OpenGL glOrtho for documentation further details.*/ + void setProjectionMatrixAsOrtho(double left, double right, + double bottom, double top, + double zNear, double zFar); + + /** Set to a 2D orthographic projection. See OpenGL glOrtho2D documentation for further details.*/ + void setProjectionMatrixAsOrtho2D(double left, double right, + double bottom, double top); + + /** Set to a perspective projection. See OpenGL glFrustum documentation for further details.*/ + void setProjectionMatrixAsFrustum(double left, double right, + double bottom, double top, + double zNear, double zFar); + + /** Create a symmetrical perspective projection, See OpenGL gluPerspective documentation for further details. + * Aspect ratio is defined as width/height.*/ + void setProjectionMatrixAsPerspective(double fovy,double aspectRatio, + double zNear, double zFar); + + /** Get the projection matrix.*/ + osg::Matrixd& getProjectionMatrix() { return _projectionMatrix; } + + /** Get the const projection matrix.*/ + const osg::Matrixd& getProjectionMatrix() const { return _projectionMatrix; } + + /** Get the othographic settings of the orthographic projection matrix. + * Returns false if matrix is not an orthographic matrix, where parameter values are undefined.*/ + bool getProjectionMatrixAsOrtho(double& left, double& right, + double& bottom, double& top, + double& zNear, double& zFar); + + /** Get the frustum setting of a perspective projection matrix. + * Returns false if matrix is not a perspective matrix, where parameter values are undefined.*/ + bool getProjectionMatrixAsFrustum(double& left, double& right, + double& bottom, double& top, + double& zNear, double& zFar); + + /** Get the frustum setting of a symmetric perspective projection matrix. + * Returns false if matrix is not a perspective matrix, where parameter values are undefined. + * Note, if matrix is not a symmetric perspective matrix then the shear will be lost. + * Asymmetric matrices occur when stereo, power walls, caves and reality center display are used. + * In these configurations one should use the 'getProjectionMatrixAsFrustum' method instead.*/ + bool getProjectionMatrixAsPerspective(double& fovy,double& aspectRatio, + double& zNear, double& zFar); + + + + /** Set the view matrix. Can be thought of as setting the position of the world relative to the camera in camera coordinates. */ + inline void setViewMatrix(const osg::Matrixf& matrix) { _viewMatrix.set(matrix); dirtyBound(); updateCameras(); } + + /** Set the view matrix. Can be thought of as setting the position of the world relative to the camera in camera coordinates. */ + inline void setViewMatrix(const osg::Matrixd& matrix) { _viewMatrix.set(matrix); dirtyBound(); updateCameras(); } + + /** Set to the position and orientation of view matrix, using the same convention as gluLookAt. */ + void setViewMatrixAsLookAt(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up); + + /** Get the view matrix. */ + osg::Matrixd& getViewMatrix() { return _viewMatrix; } + + /** Get the const view matrix. */ + const osg::Matrixd& getViewMatrix() const { return _viewMatrix; } + + /** Get to the position and orientation of a modelview matrix, using the same convention as gluLookAt. */ + void getViewMatrixAsLookAt(osg::Vec3& eye,osg::Vec3& center,osg::Vec3& up,float lookDistance=1.0f); + + /** Get the inverse view matrix.*/ + Matrixd getInverseViewMatrix() const; + + + struct CameraData + { + CameraData() {} + CameraData(osg::CameraNode* camera, const osg::Matrixd& projectionOffset, const osg::Matrixd& viewOffset): + _camera(camera), _projectionOffset(projectionOffset), _viewOffset(viewOffset) {} + + CameraData(const CameraData& rhs) : + _camera(rhs._camera), _projectionOffset(rhs._projectionOffset), _viewOffset(rhs._viewOffset) {} + + CameraData& operator = (const CameraData& rhs) + { + _camera = rhs._camera; + _projectionOffset = rhs._projectionOffset; + _viewOffset = rhs._viewOffset; + return *this; + } + + osg::ref_ptr _camera; + osg::Matrixd _projectionOffset; + osg::Matrixd _viewOffset; + }; + + bool addCamera(osg::CameraNode* camera) { return addCamera(camera, osg::Matrix::identity(), osg::Matrix::identity()); } + + bool addCamera(osg::CameraNode* camera, const osg::Matrix& projectionOffset, const osg::Matrix& viewOffse); + + bool removeCamera(unsigned int pos); + + unsigned int getNumCameras() const { return _cameras.size(); } + + CameraNode* getCamera(unsigned int pos) { return _cameras[pos]._camera.get(); } + const CameraNode* getCamera(unsigned int pos) const { return _cameras[pos]._camera.get(); } + + CameraData& getCameraData(unsigned int pos) { return _cameras[pos]; } + const CameraData& getCameraData(unsigned int pos) const { return _cameras[pos]; } + + + public: + + /** Transform method that must be defined to provide generic interface for scene graph traversals.*/ + virtual bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const; + + /** Transform method that must be defined to provide generic interface for scene graph traversals.*/ + virtual bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const; + + + protected : + + virtual ~View(); + + void updateCameras(); + + Matrixd _projectionMatrix; + Matrixd _viewMatrix; + + typedef std::vector CameraList; + CameraList _cameras; +}; + +} + +#endif diff --git a/include/osgParticle/PrecipitationEffect b/include/osgParticle/PrecipitationEffect index d6d9891ab..8b1d12f01 100644 --- a/include/osgParticle/PrecipitationEffect +++ b/include/osgParticle/PrecipitationEffect @@ -117,7 +117,7 @@ namespace osgParticle void setNumberOfVertices(unsigned int numVertices) { _numberOfVertices = numVertices; } unsigned int getNumberOfVertices() const { return _numberOfVertices; } - virtual void drawImplementation(osg::State& state) const; + virtual void drawImplementation(osg::RenderInfo& renderInfo) const; struct Cell { diff --git a/include/osgProducer/OsgCameraGroup b/include/osgProducer/OsgCameraGroup index b11451e26..58eff37a8 100644 --- a/include/osgProducer/OsgCameraGroup +++ b/include/osgProducer/OsgCameraGroup @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -233,6 +234,8 @@ class OSGPRODUCER_EXPORT OsgCameraGroup : public Producer::CameraGroup GraphicsContextList _gcList; SceneHandlerList _shvec; + osg::ref_ptr _view; + osg::ref_ptr _realizeCallback; osg::ref_ptr _ds; diff --git a/include/osgText/FadeText b/include/osgText/FadeText new file mode 100644 index 000000000..128915a21 --- /dev/null +++ b/include/osgText/FadeText @@ -0,0 +1,51 @@ +/* -*-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 OSGTEXT_FADETEXT +#define OSGTEXT_FADETEXT 1 + +#include + +namespace osgText { + + +class OSGTEXT_EXPORT FadeText : public osgText::Text +{ +public: + + FadeText(); + FadeText(const Text& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Object(osgText,FadeText) + + typedef std::map ViewBlendColourMap; + + ViewBlendColourMap& getViewBlendColourMap() { return _viewBlendColourMap; } + const ViewBlendColourMap& getViewBlendColourMap() const { return _viewBlendColourMap; } + + /** Draw the text.*/ + virtual void drawImplementation(osg::RenderInfo& renderInfo) const; + +protected: + + virtual ~FadeText() {} + + void init(); + + mutable ViewBlendColourMap _viewBlendColourMap; +}; + +} + + +#endif diff --git a/include/osgText/Text b/include/osgText/Text index bd62de38e..82fa11bcf 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -417,7 +417,7 @@ public: unsigned int getLineCount() const { return _lineCount; } /** Draw the text.*/ - virtual void drawImplementation(osg::State& state) const; + virtual void drawImplementation(osg::RenderInfo& renderInfo) const; /** return false, osgText::Text does not support accept(AttributeFunctor&).*/ virtual bool supports(const osg::Drawable::AttributeFunctor&) const { return false; } @@ -567,12 +567,13 @@ protected: void computeColorGradientsOverall() const; void computeColorGradientsPerCharacter() const; - void drawForegroundText(osg::State& state, const GlyphQuads& glyphquad) const; - void renderOnlyForegroundText(osg::State& state) const; - void renderWithPolygonOffset(osg::State& state) const; - void renderWithNoDepthBuffer(osg::State& state) const; - void renderWithDepthRange(osg::State& state) const; - void renderWithStencilBuffer(osg::State& state) const; + void drawImplementation(osg::State& state, const osg::Vec4& colorMultiplier) const; + void drawForegroundText(osg::State& state, const GlyphQuads& glyphquad, const osg::Vec4& colorMultiplier) const; + void renderOnlyForegroundText(osg::State& state, const osg::Vec4& colorMultiplier) const; + void renderWithPolygonOffset(osg::State& state, const osg::Vec4& colorMultiplier) const; + void renderWithNoDepthBuffer(osg::State& state, const osg::Vec4& colorMultiplier) const; + void renderWithDepthRange(osg::State& state, const osg::Vec4& colorMultiplier) const; + void renderWithStencilBuffer(osg::State& state, const osg::Vec4& colorMultiplier) const; BackdropType _backdropType; BackdropImplementation _backdropImplementation; diff --git a/include/osgUtil/CullVisitor b/include/osgUtil/CullVisitor index 045936733..7bc1fc3e2 100644 --- a/include/osgUtil/CullVisitor +++ b/include/osgUtil/CullVisitor @@ -239,9 +239,13 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac } - void setState(osg::State* state) { _state = state; } - osg::State* getState() { return _state.get(); } - const osg::State* getState() const { return _state.get(); } + void setState(osg::State* state) { _renderInfo.setState(state); } + osg::State* getState() { return _renderInfo.getState(); } + const osg::State* getState() const { return _renderInfo.getState(); } + + void setRenderInfo(osg::RenderInfo& renderInfo) { _renderInfo = renderInfo; } + osg::RenderInfo& getRenderInfo() { return _renderInfo; } + const osg::RenderInfo& getRenderInfo() const { return _renderInfo; } protected: @@ -283,7 +287,7 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac unsigned int _numberOfEncloseOverrideRenderBinDetails; - osg::ref_ptr _state; + osg::RenderInfo _renderInfo; struct MatrixPlanesDrawables diff --git a/include/osgUtil/RenderBin b/include/osgUtil/RenderBin index cab19bde0..d3e97a392 100644 --- a/include/osgUtil/RenderBin +++ b/include/osgUtil/RenderBin @@ -125,13 +125,13 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object - virtual void draw(osg::State& state,RenderLeaf*& previous); + virtual void draw(osg::RenderInfo& renderInfo,RenderLeaf*& previous); - virtual void drawImplementation(osg::State& state,RenderLeaf*& previous); + virtual void drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& previous); struct DrawCallback : public osg::Referenced { - virtual void drawImplementation(RenderBin* bin,osg::State& state,RenderLeaf*& previous) = 0; + virtual void drawImplementation(RenderBin* bin,osg::RenderInfo& renderInfo,RenderLeaf*& previous) = 0; }; void setDrawCallback(DrawCallback* drawCallback) { _drawCallback = drawCallback; } diff --git a/include/osgUtil/RenderLeaf b/include/osgUtil/RenderLeaf index b02363515..5eda6c771 100644 --- a/include/osgUtil/RenderLeaf +++ b/include/osgUtil/RenderLeaf @@ -60,7 +60,7 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced _depth = 0.0f; } - virtual void render(osg::State& state,RenderLeaf* previous); + virtual void render(osg::RenderInfo& renderInfo,RenderLeaf* previous); /// Allow StateGraph to change the RenderLeaf's _parent. friend class osgUtil::StateGraph; diff --git a/include/osgUtil/RenderStage b/include/osgUtil/RenderStage index 511381c18..a6d5eddcc 100644 --- a/include/osgUtil/RenderStage +++ b/include/osgUtil/RenderStage @@ -127,7 +127,7 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin bool getCameraRequiresSetUp() const { return _cameraRequiresSetUp; } /** Attempt the set the RenderStage from the Camera settings.*/ - void runCameraSetUp(osg::State& state); + void runCameraSetUp(osg::RenderInfo& renderInfo); void setTexture(osg::Texture* texture, unsigned int level = 0, unsigned int face=0) { _texture = texture; _level = level; _face = face; } osg::Texture* getTexture() { return _texture.get(); } @@ -177,19 +177,19 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin getPositionalStateContainer()->addPositionedTextureAttribute(textureUnit, matrix,attr); } - void copyTexture(osg::State& state); + void copyTexture(osg::RenderInfo& renderInfo); virtual void sort(); - virtual void drawPreRenderStages(osg::State& state,RenderLeaf*& previous); + virtual void drawPreRenderStages(osg::RenderInfo& renderInfo,RenderLeaf*& previous); - virtual void draw(osg::State& state,RenderLeaf*& previous); + virtual void draw(osg::RenderInfo& renderInfo,RenderLeaf*& previous); - virtual void drawInner(osg::State& state,RenderLeaf*& previous, bool& doCopyTexture); + virtual void drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, bool& doCopyTexture); - virtual void drawPostRenderStages(osg::State& state,RenderLeaf*& previous); + virtual void drawPostRenderStages(osg::RenderInfo& renderInfo,RenderLeaf*& previous); - virtual void drawImplementation(osg::State& state,RenderLeaf*& previous); + virtual void drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& previous); void addToDependencyList(RenderStage* rs) { addPreRenderStage(rs); } diff --git a/include/osgUtil/SceneView b/include/osgUtil/SceneView index ff3c16c1d..50d4683f5 100644 --- a/include/osgUtil/SceneView +++ b/include/osgUtil/SceneView @@ -155,7 +155,7 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced, public osg::CullSetting /** Set the uniforms that SceneView should set set up on each frame.*/ void setActiveUniforms(int activeUniforms) { _activeUniforms = activeUniforms; } - /** Get the uniforms that SceneView should set set up on each frame.*/ + /** Get the uniforms that SceneView should set set up on each frame.*/ int getActiveUniforms() const { return _activeUniforms; } void updateUniforms(); @@ -170,10 +170,18 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced, public osg::CullSetting osg::Light* getLight() { return _light.get(); } const osg::Light* getLight() const { return _light.get(); } - void setState(osg::State* state) { _state = state; } - osg::State* getState() { return _state.get(); } - const osg::State* getState() const { return _state.get(); } + void setState(osg::State* state) { _renderInfo.setState(state); } + osg::State* getState() { return _renderInfo.getState(); } + const osg::State* getState() const { return _renderInfo.getState(); } + + void setView(osg::View* view) { _renderInfo.setView(view); } + osg::View* getView() { return _renderInfo.getView(); } + const osg::View* getView() const { return _renderInfo.getView(); } + void setRenderInfo(osg::RenderInfo& renderInfo) { _renderInfo = renderInfo; } + osg::RenderInfo& getRenderInfo() { return _renderInfo; } + const osg::RenderInfo& getRenderInfo() const { return _renderInfo; } + /** Set the projection matrix. Can be thought of as setting the lens of a camera. */ @@ -470,7 +478,7 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced, public osg::CullSetting void clearArea(int x,int y,int width,int height,const osg::Vec4& color); osg::ref_ptr _localStateSet; - osg::ref_ptr _state; + osg::RenderInfo _renderInfo; bool _initCalled; osg::ref_ptr _initVisitor; diff --git a/src/osg/BlendColor.cpp b/src/osg/BlendColor.cpp index 8c31f4165..5df2658fb 100644 --- a/src/osg/BlendColor.cpp +++ b/src/osg/BlendColor.cpp @@ -20,7 +20,7 @@ using namespace osg; BlendColor::BlendColor() : - _constantColor(0.0f,0.0f,0.0f,0.0f) + _constantColor(1.0f,1.0f,1.0f,1.0f) { } diff --git a/src/osg/CameraNode.cpp b/src/osg/CameraNode.cpp index b0cb8d635..c30dd3266 100644 --- a/src/osg/CameraNode.cpp +++ b/src/osg/CameraNode.cpp @@ -16,6 +16,7 @@ using namespace osg; CameraNode::CameraNode(): + _view(0), _clearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f)), _clearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT), _transformOrder(PRE_MULTIPLY), @@ -32,6 +33,7 @@ CameraNode::CameraNode(): CameraNode::CameraNode(const CameraNode& camera,const CopyOp& copyop): Transform(camera,copyop), CullSettings(camera), + _view(camera._view), _clearColor(camera._clearColor), _clearMask(camera._clearMask), _colorMask(camera._colorMask), diff --git a/src/osg/GNUmakefile b/src/osg/GNUmakefile index 8c857769d..041be6882 100644 --- a/src/osg/GNUmakefile +++ b/src/osg/GNUmakefile @@ -115,6 +115,7 @@ CXXFILES =\ Vec3.cpp\ Version.cpp\ VertexProgram.cpp\ + View.cpp\ Viewport.cpp\ DEF += -DOSG_LIBRARY diff --git a/src/osg/StateAttribute.cpp b/src/osg/StateAttribute.cpp index c8b153ea3..774eb0f65 100644 --- a/src/osg/StateAttribute.cpp +++ b/src/osg/StateAttribute.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include diff --git a/src/osg/View.cpp b/src/osg/View.cpp new file mode 100644 index 000000000..f42b41b53 --- /dev/null +++ b/src/osg/View.cpp @@ -0,0 +1,221 @@ +/* -*-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. +*/ +#include +#include + +using namespace osg; + +// use this cull callback to allow the camera to traverse the View's children without +// actuall having them assigned as children to the camea itself. This make the camera a +// decorator without ever directly being assigned to it. +class ViewCameraTraverseNodeCallback : public osg::NodeCallback +{ +public: + + ViewCameraTraverseNodeCallback(osg::View* view):_view(view) {} + + virtual void operator()(osg::Node*, osg::NodeVisitor* nv) + { + _view->Group::traverse(*nv); + } + + osg::View* _view; +}; + + +View::View() +{ + setReferenceFrame(osg::Transform::ABSOLUTE_RF); +} + +/** Copy constructor using CopyOp to manage deep vs shallow copy.*/ +View::View(const View& view,const CopyOp& copyop): + Transform(view,copyop), + CullSettings(view), + _projectionMatrix(view._projectionMatrix), + _viewMatrix(view._viewMatrix) +{ + // need to clone the cameras. + for(unsigned int i=0; i(cd._camera->clone(copyop)), cd._projectionOffset, cd._viewOffset); + } +} + + +View::~View() +{ + // detatch the cameras from this View to prevent dangling pointers + for(CameraList::iterator itr = _cameras.begin(); + itr != _cameras.end(); + ++itr) + { + CameraData& cd = *itr; + cd._camera->setView(0); + cd._camera->setCullCallback(0); + } +} + + +Matrixd View::getInverseViewMatrix() const +{ + Matrixd inverse; + inverse.invert(_viewMatrix); + return inverse; +} + +void View::setProjectionMatrixAsOrtho(double left, double right, + double bottom, double top, + double zNear, double zFar) +{ + setProjectionMatrix(osg::Matrixd::ortho(left, right, + bottom, top, + zNear, zFar)); +} + +void View::setProjectionMatrixAsOrtho2D(double left, double right, + double bottom, double top) +{ + setProjectionMatrix(osg::Matrixd::ortho2D(left, right, + bottom, top)); +} + +void View::setProjectionMatrixAsFrustum(double left, double right, + double bottom, double top, + double zNear, double zFar) +{ + setProjectionMatrix(osg::Matrixd::frustum(left, right, + bottom, top, + zNear, zFar)); +} + +void View::setProjectionMatrixAsPerspective(double fovy,double aspectRatio, + double zNear, double zFar) +{ + setProjectionMatrix(osg::Matrixd::perspective(fovy,aspectRatio, + zNear, zFar)); +} + +bool View::getProjectionMatrixAsOrtho(double& left, double& right, + double& bottom, double& top, + double& zNear, double& zFar) +{ + return _projectionMatrix.getOrtho(left, right, + bottom, top, + zNear, zFar); +} + +bool View::getProjectionMatrixAsFrustum(double& left, double& right, + double& bottom, double& top, + double& zNear, double& zFar) +{ + return _projectionMatrix.getFrustum(left, right, + bottom, top, + zNear, zFar); +} + +bool View::getProjectionMatrixAsPerspective(double& fovy,double& aspectRatio, + double& zNear, double& zFar) +{ + return _projectionMatrix.getPerspective(fovy, aspectRatio, zNear, zFar); +} + +void View::setViewMatrixAsLookAt(const Vec3& eye,const Vec3& center,const Vec3& up) +{ + setViewMatrix(osg::Matrixd::lookAt(eye,center,up)); +} + +void View::getViewMatrixAsLookAt(Vec3& eye,Vec3& center,Vec3& up,float lookDistance) +{ + _viewMatrix.getLookAt(eye,center,up,lookDistance); +} + + +bool View::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const +{ + if (_referenceFrame==RELATIVE_RF) + { + matrix.preMult(_viewMatrix); + } + else // absolute + { + matrix = _viewMatrix; + } + return true; +} + +bool View::computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const +{ + const Matrixd& inverse = getInverseViewMatrix(); + + if (_referenceFrame==RELATIVE_RF) + { + // note doing inverse so pre becomes post. + matrix.postMult(inverse); + } + else // absolute + { + matrix = inverse; + } + return true; +} + +void View::updateCameras() +{ + for(CameraList::iterator itr = _cameras.begin(); + itr != _cameras.end(); + ++itr) + { + CameraData& cd = *itr; + cd._camera->setProjectionMatrix(cd._projectionOffset * _projectionMatrix); + cd._camera->setViewMatrix(cd._viewOffset * _viewMatrix); + cd._camera->inheritCullSettings(*this); + } + + +} + +bool View::addCamera(osg::CameraNode* camera, const osg::Matrix& projectionOffset, const osg::Matrix& viewOffset) +{ + if (!camera) return false; + + ViewCameraTraverseNodeCallback* cb = new ViewCameraTraverseNodeCallback(this); + camera->setCullCallback(cb); + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + camera->setProjectionMatrix(projectionOffset * _projectionMatrix); + camera->setViewMatrix(viewOffset * _viewMatrix); + camera->inheritCullSettings(*this); + + _cameras.push_back(CameraData(camera, projectionOffset, viewOffset)); + + osg::notify(osg::NOTICE)<<"Added camera"<= _cameras.size()) return false; + + _cameras[pos]._camera->setView(0); + _cameras[pos]._camera->setCullCallback(0); + + _cameras.erase(_cameras.begin()+pos); + + osg::notify(osg::NOTICE)<<"Removed camera"<setActiveTextureUnit(0); glMatrixMode( GL_TEXTURE ); glPushMatrix(); } @@ -931,7 +931,7 @@ void PrecipitationEffect::PrecipitationDrawable::drawImplementation(osg::State& glLoadMatrix((*itr)->second.modelview.ptr()); } - _geometry->draw(state); + _geometry->draw(renderInfo); unsigned int numVertices = osg::minimum(_geometry->getVertexArray()->getNumElements(), _numberOfVertices); glDrawArrays(_drawType, 0, numVertices); diff --git a/src/osgProducer/OsgCameraGroup.cpp b/src/osgProducer/OsgCameraGroup.cpp index 921c807cc..ace551afd 100644 --- a/src/osgProducer/OsgCameraGroup.cpp +++ b/src/osgProducer/OsgCameraGroup.cpp @@ -510,6 +510,9 @@ bool OsgCameraGroup::realize() } _shvec.clear(); + + // create the osg::View to keep track of complete views in an OSG centric way. + _view = new osg::View; osg::Node* node = getTopMostSceneData(); if (node) @@ -549,6 +552,11 @@ bool OsgCameraGroup::realize() osgUtil::SceneView* sv = sh->getSceneView(); sv->setDefaults(_realizeSceneViewOptions); + + // note, should really compute the projection and view offsets... + // but not critical as Producer controls the CameraNode matrices via SceneView. + _view->addCamera(sv->getCamera()); + sv->setView(_view.get()); if (_renderSurfaceStateMap.count(rs)==0) { diff --git a/src/osgProducer/ViewerEventHandler.cpp b/src/osgProducer/ViewerEventHandler.cpp index 9f5384276..68c2607a4 100644 --- a/src/osgProducer/ViewerEventHandler.cpp +++ b/src/osgProducer/ViewerEventHandler.cpp @@ -225,21 +225,21 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::displayHelp() ditr!=_descriptionList.end(); ++ditr) { - (*ditr)->draw(*(sv->getState())); + (*ditr)->draw(sv->getRenderInfo()); } for(TextList::iterator oitr=_optionList.begin(); oitr!=_optionList.end(); ++oitr) { - (*oitr)->draw(*(sv->getState())); + (*oitr)->draw(sv->getRenderInfo()); } for(TextList::iterator eitr=_explanationList.begin(); eitr!=_explanationList.end(); ++eitr) { - (*eitr)->draw(*(sv->getState())); + (*eitr)->draw(sv->getRenderInfo()); } } @@ -425,7 +425,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::displayStats() // update and draw the frame rate text. - _frameRateLabelText->draw(*(sv->getState())); + _frameRateLabelText->draw(sv->getRenderInfo()); if (_fs.size()>1) { unsigned int lindex = (_index + 1) % _fs.size(); @@ -434,7 +434,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::displayStats() sprintf(tmpText,"%4.2f",1.0/timePerFrame); _frameRateCounterText->setText(tmpText); } - _frameRateCounterText->draw(*(sv->getState())); + _frameRateCounterText->draw(sv->getRenderInfo()); if (_veh->getFrameStatsMode()>=ViewerEventHandler::CAMERA_STATS) @@ -462,7 +462,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::displayStats() sprintf(tmpText,"%4.2f",1000.0*updateTime/(double)_fs.size()); _updateTimeText->setText(tmpText); - _updateTimeText->draw(*(sv->getState())); + _updateTimeText->draw(sv->getRenderInfo()); TextList::iterator itr; CameraTimes::iterator titr; @@ -472,7 +472,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::displayStats() { sprintf(tmpText,"%4.2f",1000.0*(*titr)/(double)_fs.size()); (*itr)->setText(tmpText); - (*itr)->draw(*(sv->getState())); + (*itr)->draw(sv->getRenderInfo()); } for(itr=_drawTimeText.begin(),titr = _drawTimes.begin(); @@ -481,7 +481,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::displayStats() { sprintf(tmpText,"%4.2f",1000.0*(*titr)/(double)_fs.size()); (*itr)->setText(tmpText); - (*itr)->draw(*(sv->getState())); + (*itr)->draw(sv->getRenderInfo()); } unsigned int i; @@ -495,7 +495,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::displayStats() gpuTimingsValid = true; sprintf(tmpText,"%4.2f", gpuTime); (*itr)->setText(tmpText); - (*itr)->draw(*(sv->getState())); + (*itr)->draw(sv->getRenderInfo()); } } @@ -505,7 +505,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::displayStats() { if (gpuTimingsValid || ((*itr)->getName()!="GPU")) { - (*itr)->draw(*(sv->getState())); + (*itr)->draw(sv->getRenderInfo()); } } } @@ -533,20 +533,20 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::displayStats() itr != _sceneStatsLabelList.end(); ++itr) { - (*itr)->draw(*(sv->getState())); + (*itr)->draw(sv->getRenderInfo()); } sprintf(tmpText,"%d",stats._vertexCount); _numVerticesText->setText(tmpText); - _numVerticesText->draw(*(sv->getState())); + _numVerticesText->draw(sv->getRenderInfo()); sprintf(tmpText,"%d",primitives); _numPrimitivesText->setText(tmpText); - _numPrimitivesText->draw(*(sv->getState())); + _numPrimitivesText->draw(sv->getRenderInfo()); sprintf(tmpText,"%d",stats.numDrawables); _numDrawablesText->setText(tmpText); - _numDrawablesText->draw(*(sv->getState())); + _numDrawablesText->draw(sv->getRenderInfo()); } } diff --git a/src/osgText/FadeText.cpp b/src/osgText/FadeText.cpp new file mode 100644 index 000000000..052f0c753 --- /dev/null +++ b/src/osgText/FadeText.cpp @@ -0,0 +1,233 @@ +/* -*-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. +*/ + + +#include +#include +#include +#include +#include + +using namespace osgText; + +struct FadeTextUserData : public osg::Referenced +{ + FadeTextUserData(): + _frameNumber(0) {} + + typedef std::list FadeTextList; + unsigned int _frameNumber; + FadeTextList _fadeTextInView; +}; + +struct GlobalFadeText : public osg::Referenced +{ + typedef std::set< osg::ref_ptr > UserDataSet; + typedef std::set FadeTextSet; + typedef std::map ViewUserDataMap; + typedef std::map ViewFadeTextMap; + + GlobalFadeText(): + _frameNumber(0xffffffff) + { + } + + + FadeTextUserData* createNewFadeTextUserData(osg::View* view) + { + OpenThreads::ScopedLock lock(_mutex); + + FadeTextUserData* userData = new FadeTextUserData; + + if (!userData) + { + osg::notify(osg::NOTICE)<<"Memory error, unable to create FadeTextUserData."<first; + + FadeTextSet& fadeTextSet = _viewFadeTextMap[view]; + fadeTextSet.clear(); + + for(GlobalFadeText::UserDataSet::iterator uitr = vitr->second.begin(); + uitr != vitr->second.end(); + ++uitr) + { + FadeTextUserData* userData = uitr->get(); + + int frameDelta = frameNumber - userData->_frameNumber; + if (frameDelta<=1) + { + for(FadeTextUserData::FadeTextList::iterator fitr = userData->_fadeTextInView.begin(); + fitr != userData->_fadeTextInView.end(); + ++fitr) + { + FadeText* fadeText = *fitr; + fadeTextSet.insert(fadeText); + } + } + } + + osg::notify(osg::NOTICE)<<" view="< s_globalFadeText = new GlobalFadeText; + return s_globalFadeText.get(); +} + +struct FadeTextUpdateCallback : public osg::Drawable::UpdateCallback +{ + virtual void update(osg::NodeVisitor* nv, osg::Drawable* drawable) + { + osgText::FadeText* fadeText = dynamic_cast(drawable); + if (!fadeText) return; + + unsigned int frameNumber = nv->getFrameStamp()->getFrameNumber(); + + osg::notify(osg::NOTICE)<<"Update FadeText "< FadeTextSet; + + GlobalFadeText* gft = getGlobalFadeText(); + gft->updateIfRequired(frameNumber); + + osgText::FadeText::ViewBlendColourMap& vbcm = fadeText->getViewBlendColourMap(); + + GlobalFadeText::ViewFadeTextMap& vftm = gft->_viewFadeTextMap; + for(GlobalFadeText::ViewFadeTextMap::iterator itr = vftm.begin(); + itr != vftm.end(); + ++itr) + { + osg::View* view = itr->first; + FadeTextSet& fadeTextSet = itr->second; + if (fadeTextSet.count(fadeText)==0) + { + osg::notify(osg::NOTICE)<<"Text "<second ); + } + else + { + Text::drawImplementation(*renderInfo.getState(), osg::Vec4(1.0f,1.0f,1.0f,1.0f) ); + } + + + // now pass on new details + + FadeTextUserData* userData = dynamic_cast(renderInfo.getUserData()); + if (!userData) + { + if (renderInfo.getUserData()) + { + osg::notify(osg::NOTICE)<<"Warning user data not of supported type."<createNewFadeTextUserData(renderInfo.getView()); + + if (!userData) + { + osg::notify(osg::NOTICE)<<"Memory error, unable to create FadeTextUserData."<getFrameStamp()->getFrameNumber(); + if (frameNumber != userData->_frameNumber) + { + // new frame so must reset UserData structure. + userData->_frameNumber = frameNumber; + userData->_fadeTextInView.clear(); + } + + userData->_fadeTextInView.push_back(const_cast(this)); + + osgText::Text::AutoTransformCache& atc = _autoTransformCache[renderInfo.getContextID()]; + osg::Matrix& matrix = atc._matrix; + + osg::notify(osg::NOTICE)<<"cull Matrix = "<second; - drawForegroundText(state, glyphquad); + drawForegroundText(state, glyphquad, colorMultiplier); } } -void Text::renderWithPolygonOffset(osg::State& state) const +void Text::renderWithPolygonOffset(osg::State& state, const osg::Vec4& colorMultiplier) const { unsigned int contextID = state.getContextID(); @@ -1992,14 +1997,14 @@ void Text::renderWithPolygonOffset(osg::State& state) const // Reset the polygon offset so the foreground text is on top glPolygonOffset(0.0f,0.0f); - drawForegroundText(state, glyphquad); + drawForegroundText(state, glyphquad, colorMultiplier); } glPopAttrib(); } -void Text::renderWithNoDepthBuffer(osg::State& state) const +void Text::renderWithNoDepthBuffer(osg::State& state, const osg::Vec4& colorMultiplier) const { unsigned int contextID = state.getContextID(); @@ -2042,14 +2047,14 @@ void Text::renderWithNoDepthBuffer(osg::State& state) const } } - drawForegroundText(state, glyphquad); + drawForegroundText(state, glyphquad, colorMultiplier); } glPopAttrib(); } // This idea comes from Paul Martz's OpenGL FAQ: 13.050 -void Text::renderWithDepthRange(osg::State& state) const +void Text::renderWithDepthRange(osg::State& state, const osg::Vec4& colorMultiplier) const { unsigned int contextID = state.getContextID(); @@ -2099,13 +2104,13 @@ void Text::renderWithDepthRange(osg::State& state) const glDepthRange(0.0, 1.0); - drawForegroundText(state, glyphquad); + drawForegroundText(state, glyphquad, colorMultiplier); } glPopAttrib(); } -void Text::renderWithStencilBuffer(osg::State& state) const +void Text::renderWithStencilBuffer(osg::State& state, const osg::Vec4& colorMultiplier) const { /* Here are the steps: * 1) Disable drawing color @@ -2256,7 +2261,7 @@ void Text::renderWithStencilBuffer(osg::State& state) const } } - drawForegroundText(state, glyphquad); + drawForegroundText(state, glyphquad, colorMultiplier); } glPopAttrib(); diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index 3506544ec..9a08f2cca 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -740,7 +740,7 @@ void CullVisitor::apply(Geode& node) if( drawable->getCullCallback() ) { - if( drawable->getCullCallback()->cull( this, drawable, _state.valid()?_state.get():NULL ) == true ) + if( drawable->getCullCallback()->cull( this, drawable, &_renderInfo ) == true ) continue; } diff --git a/src/osgUtil/RenderBin.cpp b/src/osgUtil/RenderBin.cpp index 3973e6846..1f6599bb1 100644 --- a/src/osgUtil/RenderBin.cpp +++ b/src/osgUtil/RenderBin.cpp @@ -352,17 +352,19 @@ RenderBin* RenderBin::find_or_insert(int binNum,const std::string& binName) return rb; } -void RenderBin::draw(osg::State& state,RenderLeaf*& previous) +void RenderBin::draw(osg::RenderInfo& renderInfo,RenderLeaf*& previous) { if (_drawCallback.valid()) { - _drawCallback->drawImplementation(this,state,previous); + _drawCallback->drawImplementation(this,renderInfo,previous); } - else drawImplementation(state,previous); + else drawImplementation(renderInfo,previous); } -void RenderBin::drawImplementation(osg::State& state,RenderLeaf*& previous) +void RenderBin::drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& previous) { + osg::State& state = *renderInfo.getState(); + // osg::notify(osg::NOTICE)<<"begin RenderBin::drawImplementation "<first<0; ++rbitr) { - rbitr->second->draw(state,previous); + rbitr->second->draw(renderInfo,previous); } @@ -391,7 +393,7 @@ void RenderBin::drawImplementation(osg::State& state,RenderLeaf*& previous) ++rlitr) { RenderLeaf* rl = *rlitr; - rl->render(state,previous); + rl->render(renderInfo,previous); previous = rl; } @@ -407,7 +409,7 @@ void RenderBin::drawImplementation(osg::State& state,RenderLeaf*& previous) ++dw_itr) { RenderLeaf* rl = dw_itr->get(); - rl->render(state,previous); + rl->render(renderInfo,previous); previous = rl; } @@ -419,7 +421,7 @@ void RenderBin::drawImplementation(osg::State& state,RenderLeaf*& previous) rbitr!=_bins.end(); ++rbitr) { - rbitr->second->draw(state,previous); + rbitr->second->draw(renderInfo,previous); } if (_stateset.valid()) diff --git a/src/osgUtil/RenderLeaf.cpp b/src/osgUtil/RenderLeaf.cpp index 95c1d7b03..221bd794c 100644 --- a/src/osgUtil/RenderLeaf.cpp +++ b/src/osgUtil/RenderLeaf.cpp @@ -17,8 +17,10 @@ using namespace osg; using namespace osgUtil; -void RenderLeaf::render(State& state,RenderLeaf* previous) +void RenderLeaf::render(osg::RenderInfo& renderInfo,RenderLeaf* previous) { + osg::State& state = *renderInfo.getState(); + // don't draw this leaf if the abort rendering flag has been set. if (state.getAbortRendering()) { @@ -55,7 +57,7 @@ void RenderLeaf::render(State& state,RenderLeaf* previous) // draw the drawable - _drawable->draw(state); + _drawable->draw(renderInfo); } else { @@ -69,7 +71,7 @@ void RenderLeaf::render(State& state,RenderLeaf* previous) state.apply(_parent->_stateset); // draw the drawable - _drawable->draw(state); + _drawable->draw(renderInfo); } // osg::notify(osg::NOTICE)<<"RenderLeaf "<<_drawable->getName()<<" "<<_depth<second->draw(state,previous); + itr->second->draw(renderInfo,previous); } //cout << "Done Drawing prerendering stages "<x()<<","<< _viewport->y()<<","<< _viewport->width()<<","<< _viewport->height()<getRenderTargetImplementation(); osg::CameraNode::RenderTargetImplementation renderTargetFallback = _camera->getRenderTargetFallback(); @@ -620,8 +622,10 @@ void RenderStage::runCameraSetUp(osg::State& state) } -void RenderStage::copyTexture(osg::State& state) +void RenderStage::copyTexture(osg::RenderInfo& renderInfo) { + osg::State& state = *renderInfo.getState(); + if (_readBuffer != GL_NONE) { glReadBuffer(_readBuffer); @@ -690,8 +694,10 @@ void RenderStage::copyTexture(osg::State& state) #endif } -void RenderStage::drawInner(osg::State& state,RenderLeaf*& previous, bool& doCopyTexture) +void RenderStage::drawInner(osg::RenderInfo& renderInfo,RenderLeaf*& previous, bool& doCopyTexture) { + osg::State& state = *renderInfo.getState(); + if (_drawBuffer != GL_NONE) { glDrawBuffer(_drawBuffer); @@ -711,7 +717,7 @@ void RenderStage::drawInner(osg::State& state,RenderLeaf*& previous, bool& doCop } // do the drawing itself. - RenderBin::draw(state,previous); + RenderBin::draw(renderInfo,previous); if(state.getCheckForGLErrors()!=osg::State::NEVER_CHECK_GL_ERRORS) @@ -730,7 +736,7 @@ void RenderStage::drawInner(osg::State& state,RenderLeaf*& previous, bool& doCop // now copy the rendered image to attached texture. if (doCopyTexture) { - copyTexture(state); + copyTexture(renderInfo); } if (_image.valid()) @@ -784,9 +790,10 @@ void RenderStage::drawInner(osg::State& state,RenderLeaf*& previous, bool& doCop struct DrawInnerOperation : public osg::GraphicsThread::Operation { - DrawInnerOperation(RenderStage* stage) : + DrawInnerOperation(RenderStage* stage, osg::RenderInfo& renderInfo) : osg::GraphicsThread::Operation("DrawInnerStage",false), - _stage(stage) {} + _stage(stage), + _renderInfo(renderInfo) {} virtual void operator() (osg::GraphicsContext* context) { @@ -795,15 +802,17 @@ struct DrawInnerOperation : public osg::GraphicsThread::Operation { RenderLeaf* previous = 0; bool doCopyTexture = false; - _stage->drawInner(*(context->getState()), previous, doCopyTexture); + _renderInfo.setState(context->getState()); + _stage->drawInner(_renderInfo, previous, doCopyTexture); } } RenderStage* _stage; + RenderInfo _renderInfo; }; -void RenderStage::draw(osg::State& state,RenderLeaf*& previous) +void RenderStage::draw(osg::RenderInfo& renderInfo,RenderLeaf*& previous) { if (_stageDrawnThisFrame) return; @@ -811,18 +820,20 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous) // note, SceneView does call to drawPreRenderStages explicitly // so there is no need to call it here. - drawPreRenderStages(state,previous); + drawPreRenderStages(renderInfo,previous); if (_cameraRequiresSetUp) { - runCameraSetUp(state); + runCameraSetUp(renderInfo); } + osg::State& state = *renderInfo.getState(); osg::State* useState = &state; osg::GraphicsContext* callingContext = state.getGraphicsContext(); osg::GraphicsContext* useContext = callingContext; osg::GraphicsThread* useThread = 0; + osg::RenderInfo useRenderInfo(renderInfo); if (_graphicsContext.valid() && _graphicsContext != callingContext) { @@ -833,6 +844,7 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous) useState = _graphicsContext->getState(); useContext = _graphicsContext.get(); useThread = useContext->getGraphicsThread(); + useRenderInfo.setState(useState); // syncronize the frame stamps useState->setFrameStamp(const_cast(state.getFrameStamp())); @@ -846,13 +858,13 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous) if (useThread) { - useThread->add(new DrawInnerOperation( this ), true); + useThread->add(new DrawInnerOperation( this, renderInfo ), true); doCopyTexture = false; } else { - drawInner( *useState, previous, doCopyTexture); + drawInner( useRenderInfo, previous, doCopyTexture); } @@ -865,7 +877,7 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous) callingContext->makeContextCurrent(useContext); } - copyTexture(state); + copyTexture(renderInfo); } if (_camera && _camera->getPostDrawCallback()) @@ -887,11 +899,12 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous) // place the post draw here temprorarily while we figure out how // best to do SceneView. - drawPostRenderStages(state,previous); + drawPostRenderStages(renderInfo,previous); } -void RenderStage::drawImplementation(osg::State& state,RenderLeaf*& previous) +void RenderStage::drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& previous) { + osg::State& state = *renderInfo.getState(); if (!_viewport) { @@ -952,12 +965,12 @@ void RenderStage::drawImplementation(osg::State& state,RenderLeaf*& previous) } // draw the children and local. - RenderBin::drawImplementation(state,previous); + RenderBin::drawImplementation(renderInfo,previous); state.apply(); } -void RenderStage::drawPostRenderStages(osg::State& state,RenderLeaf*& previous) +void RenderStage::drawPostRenderStages(osg::RenderInfo& renderInfo,RenderLeaf*& previous) { if (_postRenderList.empty()) return; @@ -966,7 +979,7 @@ void RenderStage::drawPostRenderStages(osg::State& state,RenderLeaf*& previous) itr!=_postRenderList.end(); ++itr) { - itr->second->draw(state,previous); + itr->second->draw(renderInfo,previous); } //cout << "Done Drawing prerendering stages "<x()<<","<< _viewport->y()<<","<< _viewport->width()<<","<< _viewport->height()<setFrameStamp(_frameStamp.get()); GLObjectsVisitor* dlv = dynamic_cast(_initVisitor.get()); - if (dlv) dlv->setState(_state.get()); + if (dlv) dlv->setState(_renderInfo.getState()); if (_frameStamp.valid()) { @@ -460,14 +460,16 @@ void SceneView::cull() // update the active uniforms updateUniforms(); - if (!_state) + if (!_renderInfo.getState()) { osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView::_state attached, creating a default state automatically."<< std::endl; // note the constructor for osg::State will set ContextID to 0 which will be fine to single context graphics // applications which is ok for most apps, but not multiple context/pipe applications. - _state = new osg::State; + _renderInfo.setState(new osg::State); } + + osg::State* state = _renderInfo.getState(); if (!_localStateSet) { @@ -477,8 +479,8 @@ void SceneView::cull() // we in theory should be able to be able to bypass reset, but we'll call it just incase. //_state->reset(); - _state->setFrameStamp(_frameStamp.get()); - _state->setDisplaySettings(_displaySettings.get()); + state->setFrameStamp(_frameStamp.get()); + state->setDisplaySettings(_displaySettings.get()); if (!_cullVisitor) @@ -655,7 +657,7 @@ void SceneView::cullStage(const osg::Matrixd& projection,const osg::Matrixd& mod cullVisitor->setStateGraph(rendergraph); cullVisitor->setRenderStage(renderStage); - cullVisitor->setState( _state.get() ); + cullVisitor->setRenderInfo( _renderInfo ); renderStage->reset(); @@ -740,51 +742,57 @@ void SceneView::releaseAllGLObjects() { if (!_camera) return; - _camera->releaseGLObjects(_state.get()); + _camera->releaseGLObjects(_renderInfo.getState()); // we need to reset State as it keeps handles to Program objects. - if (_state.valid()) _state->reset(); + if (_renderInfo.getState()) _renderInfo.getState()->reset(); } void SceneView::flushAllDeletedGLObjects() { + osg::State* state = _renderInfo.getState(); + _requiresFlush = false; double availableTime = 100.0f; - double currentTime = _state->getFrameStamp()?_state->getFrameStamp()->getReferenceTime():0.0; + double currentTime = state->getFrameStamp()?state->getFrameStamp()->getReferenceTime():0.0; - osg::FrameBufferObject::flushDeletedFrameBufferObjects(_state->getContextID(),currentTime,availableTime); - osg::RenderBuffer::flushDeletedRenderBuffers(_state->getContextID(),currentTime,availableTime); - osg::Texture::flushAllDeletedTextureObjects(_state->getContextID()); - osg::Drawable::flushAllDeletedDisplayLists(_state->getContextID()); - osg::Drawable::flushDeletedVertexBufferObjects(_state->getContextID(),currentTime,availableTime); - osg::VertexProgram::flushDeletedVertexProgramObjects(_state->getContextID(),currentTime,availableTime); - osg::FragmentProgram::flushDeletedFragmentProgramObjects(_state->getContextID(),currentTime,availableTime); - osg::Program::flushDeletedGlPrograms(_state->getContextID(),currentTime,availableTime); - osg::Shader::flushDeletedGlShaders(_state->getContextID(),currentTime,availableTime); + osg::FrameBufferObject::flushDeletedFrameBufferObjects(state->getContextID(),currentTime,availableTime); + osg::RenderBuffer::flushDeletedRenderBuffers(state->getContextID(),currentTime,availableTime); + osg::Texture::flushAllDeletedTextureObjects(state->getContextID()); + osg::Drawable::flushAllDeletedDisplayLists(state->getContextID()); + osg::Drawable::flushDeletedVertexBufferObjects(state->getContextID(),currentTime,availableTime); + osg::VertexProgram::flushDeletedVertexProgramObjects(state->getContextID(),currentTime,availableTime); + osg::FragmentProgram::flushDeletedFragmentProgramObjects(state->getContextID(),currentTime,availableTime); + osg::Program::flushDeletedGlPrograms(state->getContextID(),currentTime,availableTime); + osg::Shader::flushDeletedGlShaders(state->getContextID(),currentTime,availableTime); } void SceneView::flushDeletedGLObjects(double& availableTime) { + osg::State* state = _renderInfo.getState(); + _requiresFlush = false; - double currentTime = _state->getFrameStamp()?_state->getFrameStamp()->getReferenceTime():0.0; + double currentTime = state->getFrameStamp()?state->getFrameStamp()->getReferenceTime():0.0; - osg::FrameBufferObject::flushDeletedFrameBufferObjects(_state->getContextID(),currentTime,availableTime); - osg::RenderBuffer::flushDeletedRenderBuffers(_state->getContextID(),currentTime,availableTime); - osg::Texture::flushDeletedTextureObjects(_state->getContextID(),currentTime,availableTime); - osg::Drawable::flushDeletedDisplayLists(_state->getContextID(),availableTime); - osg::Drawable::flushDeletedVertexBufferObjects(_state->getContextID(),currentTime,availableTime); - osg::VertexProgram::flushDeletedVertexProgramObjects(_state->getContextID(),currentTime,availableTime); - osg::FragmentProgram::flushDeletedFragmentProgramObjects(_state->getContextID(),currentTime,availableTime); - osg::Program::flushDeletedGlPrograms(_state->getContextID(),currentTime,availableTime); - osg::Shader::flushDeletedGlShaders(_state->getContextID(),currentTime,availableTime); + osg::FrameBufferObject::flushDeletedFrameBufferObjects(state->getContextID(),currentTime,availableTime); + osg::RenderBuffer::flushDeletedRenderBuffers(state->getContextID(),currentTime,availableTime); + osg::Texture::flushDeletedTextureObjects(state->getContextID(),currentTime,availableTime); + osg::Drawable::flushDeletedDisplayLists(state->getContextID(),availableTime); + osg::Drawable::flushDeletedVertexBufferObjects(state->getContextID(),currentTime,availableTime); + osg::VertexProgram::flushDeletedVertexProgramObjects(state->getContextID(),currentTime,availableTime); + osg::FragmentProgram::flushDeletedFragmentProgramObjects(state->getContextID(),currentTime,availableTime); + osg::Program::flushDeletedGlPrograms(state->getContextID(),currentTime,availableTime); + osg::Shader::flushDeletedGlShaders(state->getContextID(),currentTime,availableTime); } void SceneView::draw() { + osg::State* state = _renderInfo.getState(); + // note, to support multi-pipe systems the deletion of OpenGL display list // and texture objects is deferred until the OpenGL context is the correct // context for when the object were originally created. Here we know what @@ -799,7 +807,7 @@ void SceneView::draw() // assume the the draw which is about to happen could generate GL objects that need flushing in the next frame. _requiresFlush = true; - _state->setInitialViewMatrix(new osg::RefMatrix(getViewMatrix())); + state->setInitialViewMatrix(new osg::RefMatrix(getViewMatrix())); RenderLeaf* previous = NULL; if (_displaySettings.valid() && _displaySettings->getStereo()) @@ -831,12 +839,12 @@ void SceneView::draw() _renderStageRight->setDrawBuffer(GL_BACK_RIGHT); _renderStageRight->setReadBuffer(GL_BACK_RIGHT); - _renderStageLeft->drawPreRenderStages(*_state,previous); - _renderStageRight->drawPreRenderStages(*_state,previous); + _renderStageLeft->drawPreRenderStages(_renderInfo,previous); + _renderStageRight->drawPreRenderStages(_renderInfo,previous); - _renderStageLeft->draw(*_state,previous); + _renderStageLeft->draw(_renderInfo,previous); - _renderStageRight->draw(*_state,previous); + _renderStageRight->draw(_renderInfo,previous); } break; @@ -854,8 +862,8 @@ void SceneView::draw() _localStateSet->setAttribute(getViewport()); - _renderStageLeft->drawPreRenderStages(*_state,previous); - _renderStageRight->drawPreRenderStages(*_state,previous); + _renderStageLeft->drawPreRenderStages(_renderInfo,previous); + _renderStageRight->drawPreRenderStages(_renderInfo,previous); // ensure that left eye color planes are active. @@ -875,7 +883,7 @@ void SceneView::draw() _localStateSet->setAttribute(leftColorMask); // draw left eye. - _renderStageLeft->draw(*_state,previous); + _renderStageLeft->draw(_renderInfo,previous); @@ -897,7 +905,7 @@ void SceneView::draw() _renderStageRight->setColorMask(rightColorMask); // draw right eye. - _renderStageRight->draw(*_state,previous); + _renderStageRight->draw(_renderInfo,previous); } break; @@ -926,8 +934,8 @@ void SceneView::draw() _renderStageLeft->setColorMask(cmask); _renderStageRight->setColorMask(cmask); - _renderStageLeft->drawPreRenderStages(*_state,previous); - _renderStageRight->drawPreRenderStages(*_state,previous); + _renderStageLeft->drawPreRenderStages(_renderInfo,previous); + _renderStageRight->drawPreRenderStages(_renderInfo,previous); int separation = _displaySettings->getSplitStereoHorizontalSeparation(); @@ -948,21 +956,21 @@ void SceneView::draw() { _localStateSet->setAttribute(viewportLeft.get()); _renderStageLeft->setViewport(viewportLeft.get()); - _renderStageLeft->draw(*_state,previous); + _renderStageLeft->draw(_renderInfo,previous); _localStateSet->setAttribute(viewportRight.get()); _renderStageRight->setViewport(viewportRight.get()); - _renderStageRight->draw(*_state,previous); + _renderStageRight->draw(_renderInfo,previous); } else { _localStateSet->setAttribute(viewportRight.get()); _renderStageLeft->setViewport(viewportRight.get()); - _renderStageLeft->draw(*_state,previous); + _renderStageLeft->draw(_renderInfo,previous); _localStateSet->setAttribute(viewportLeft.get()); _renderStageRight->setViewport(viewportLeft.get()); - _renderStageRight->draw(*_state,previous); + _renderStageRight->draw(_renderInfo,previous); } } @@ -992,8 +1000,8 @@ void SceneView::draw() _renderStageLeft->setColorMask(cmask); _renderStageRight->setColorMask(cmask); - _renderStageLeft->drawPreRenderStages(*_state,previous); - _renderStageRight->drawPreRenderStages(*_state,previous); + _renderStageLeft->drawPreRenderStages(_renderInfo,previous); + _renderStageRight->drawPreRenderStages(_renderInfo,previous); int separation = _displaySettings->getSplitStereoVerticalSeparation(); @@ -1013,21 +1021,21 @@ void SceneView::draw() { _localStateSet->setAttribute(viewportTop.get()); _renderStageLeft->setViewport(viewportTop.get()); - _renderStageLeft->draw(*_state,previous); + _renderStageLeft->draw(_renderInfo,previous); _localStateSet->setAttribute(viewportBottom.get()); _renderStageRight->setViewport(viewportBottom.get()); - _renderStageRight->draw(*_state,previous); + _renderStageRight->draw(_renderInfo,previous); } else { _localStateSet->setAttribute(viewportBottom.get()); _renderStageLeft->setViewport(viewportBottom.get()); - _renderStageLeft->draw(*_state,previous); + _renderStageLeft->draw(_renderInfo,previous); _localStateSet->setAttribute(viewportTop.get()); _renderStageRight->setViewport(viewportTop.get()); - _renderStageRight->draw(*_state,previous); + _renderStageRight->draw(_renderInfo,previous); } } break; @@ -1055,8 +1063,8 @@ void SceneView::draw() _renderStage->setColorMask(cmask); _localStateSet->setAttribute(getViewport()); - _renderStage->drawPreRenderStages(*_state,previous); - _renderStage->draw(*_state,previous); + _renderStage->drawPreRenderStages(_renderInfo,previous); + _renderStage->draw(_renderInfo,previous); } break; case(osg::DisplaySettings::VERTICAL_INTERLACE): @@ -1077,8 +1085,8 @@ void SceneView::draw() _renderStageLeft->setColorMask(cmask); _renderStageRight->setColorMask(cmask); - _renderStageLeft->drawPreRenderStages(*_state,previous); - _renderStageRight->drawPreRenderStages(*_state,previous); + _renderStageLeft->drawPreRenderStages(_renderInfo,previous); + _renderStageRight->drawPreRenderStages(_renderInfo,previous); glEnable(GL_STENCIL_TEST); @@ -1086,7 +1094,7 @@ void SceneView::draw() _interlacedStereoStencilWidth != getViewport()->width() || _interlacedStereoStencilHeight != getViewport()->height() ) { - getViewport()->apply(*_state); + getViewport()->apply(*state); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(getViewport()->x(), getViewport()->width(), getViewport()->y(), getViewport()->height(), -1.0, 1.0); @@ -1117,10 +1125,10 @@ void SceneView::draw() glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, 0, ~0u); - _renderStageLeft->draw(*_state,previous); + _renderStageLeft->draw(_renderInfo,previous); glStencilFunc(GL_NOTEQUAL, 0, ~0u); - _renderStageRight->draw(*_state,previous); + _renderStageRight->draw(_renderInfo,previous); glDisable(GL_STENCIL_TEST); } break; @@ -1142,8 +1150,8 @@ void SceneView::draw() _renderStageLeft->setColorMask(cmask); _renderStageRight->setColorMask(cmask); - _renderStageLeft->drawPreRenderStages(*_state,previous); - _renderStageRight->drawPreRenderStages(*_state,previous); + _renderStageLeft->drawPreRenderStages(_renderInfo,previous); + _renderStageRight->drawPreRenderStages(_renderInfo,previous); glEnable(GL_STENCIL_TEST); @@ -1151,7 +1159,7 @@ void SceneView::draw() _interlacedStereoStencilWidth != getViewport()->width() || _interlacedStereoStencilHeight != getViewport()->height() ) { - getViewport()->apply(*_state); + getViewport()->apply(*state); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(getViewport()->x(), getViewport()->width(), getViewport()->y(), getViewport()->height(), -1.0, 1.0); @@ -1182,10 +1190,10 @@ void SceneView::draw() glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, 0, ~0u); - _renderStageLeft->draw(*_state,previous); + _renderStageLeft->draw(_renderInfo,previous); glStencilFunc(GL_NOTEQUAL, 0, ~0u); - _renderStageRight->draw(*_state,previous); + _renderStageRight->draw(_renderInfo,previous); glDisable(GL_STENCIL_TEST); } break; @@ -1223,20 +1231,20 @@ void SceneView::draw() _renderStage->setColorMask(cmask); // bog standard draw. - _renderStage->drawPreRenderStages(*_state,previous); - _renderStage->draw(*_state,previous); + _renderStage->drawPreRenderStages(_renderInfo,previous); + _renderStage->draw(_renderInfo,previous); } // re apply the defalt OGL state. - _state->popAllStateSets(); - _state->apply(); + state->popAllStateSets(); + state->apply(); if (_camera->getPostDrawCallback()) { (*(_camera->getPostDrawCallback()))(*_camera); } - if (_state->getCheckForGLErrors()!=osg::State::NEVER_CHECK_GL_ERRORS) + if (state->getCheckForGLErrors()!=osg::State::NEVER_CHECK_GL_ERRORS) { GLenum errorNo = glGetError(); if (errorNo!=GL_NO_ERROR) @@ -1245,7 +1253,7 @@ void SceneView::draw() // go into debug mode of OGL error in a fine grained way to help // track down OpenGL errors. - _state->setCheckForGLErrors(osg::State::ONCE_PER_ATTRIBUTE); + state->setCheckForGLErrors(osg::State::ONCE_PER_ATTRIBUTE); } } } @@ -1309,7 +1317,7 @@ void SceneView::clearArea(int x,int y,int width,int height,const osg::Vec4& colo osg::ref_ptr viewport = new osg::Viewport; viewport->setViewport(x,y,width,height); - _state->applyAttribute(viewport.get()); + _renderInfo.getState()->applyAttribute(viewport.get()); glScissor( x, y, width, height ); glEnable( GL_SCISSOR_TEST );