From 296865e250d227f8689f2c73992875d16c446514 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 19 Dec 2001 00:38:23 +0000 Subject: [PATCH] Adding support for controlling visual settings via environmental variables and command line paramters. Including support for stereo and stencil buffer. --- VisualStudio/osg/osg.dsp | 16 ++ VisualStudio/osgPlugins/osg/dot_osg.dsp | 4 + include/osg/ColorMatrix | 57 +++++++ include/osg/State | 16 +- include/osg/StateAttribute | 80 ++++----- include/osg/Viewport | 7 +- include/osg/VisualsSettings | 115 +++++++++++++ include/osgDB/ReadFile | 6 +- include/osgDB/Registry | 10 ++ include/osgGLUT/Viewer | 8 +- include/osgUtil/SceneView | 34 +--- include/osgUtil/VisualsRequirementsVisitor | 43 +---- src/Demos/sgv/sgv.cpp | 120 +++----------- src/osg/ColorMatrix.cpp | 22 +++ src/osg/Makefile | 4 + src/osg/VisualsSettings.cpp | 178 +++++++++++++++++++++ src/osgDB/ReadFile.cpp | 50 ++++++ src/osgDB/Registry.cpp | 52 ++++++ src/osgGLUT/Viewer.cpp | 45 ++++-- src/osgPlugins/osg/ColorMatrix.cpp | 67 ++++++++ src/osgPlugins/osg/Makefile | 1 + src/osgPlugins/osg/TexMat.cpp | 8 +- src/osgUtil/SceneView.cpp | 152 ++++++++++-------- src/osgUtil/VisualsRequirementsVisitor.cpp | 30 ++-- 24 files changed, 825 insertions(+), 300 deletions(-) create mode 100644 include/osg/ColorMatrix create mode 100644 include/osg/VisualsSettings create mode 100644 src/osg/ColorMatrix.cpp create mode 100644 src/osg/VisualsSettings.cpp create mode 100644 src/osgPlugins/osg/ColorMatrix.cpp diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index a59f38035..c071b2318 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -121,6 +121,10 @@ SOURCE=..\..\src\osg\ColorMask.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osg\ColorMatrix.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osg\CullFace.cpp # End Source File # Begin Source File @@ -291,6 +295,10 @@ SOURCE=..\..\src\osg\Version.cpp SOURCE=..\..\src\osg\Viewport.cpp # End Source File +# Begin Source File + +SOURCE=..\..\src\osg\VisualsSettings.cpp +# End Source File # End Group # Begin Group "Header Files" @@ -333,6 +341,10 @@ SOURCE=..\..\Include\Osg\ColorMask # End Source File # Begin Source File +SOURCE=..\..\Include\Osg\ColorMatrix +# End Source File +# Begin Source File + SOURCE=..\..\Include\Osg\CullFace # End Source File # Begin Source File @@ -559,6 +571,10 @@ SOURCE=..\..\Include\Osg\Version SOURCE=..\..\include\osg\Viewport # End Source File +# Begin Source File + +SOURCE=..\..\include\osg\VisualsSettings +# End Source File # End Group # Begin Group "Resource Files" diff --git a/VisualStudio/osgPlugins/osg/dot_osg.dsp b/VisualStudio/osgPlugins/osg/dot_osg.dsp index 3c2f00c0b..3a85b7ce0 100755 --- a/VisualStudio/osgPlugins/osg/dot_osg.dsp +++ b/VisualStudio/osgPlugins/osg/dot_osg.dsp @@ -110,6 +110,10 @@ SOURCE=..\..\..\src\osgPlugins\osg\ColorMask.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\osg\ColorMatrix.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\osg\CullFace.cpp # End Source File # Begin Source File diff --git a/include/osg/ColorMatrix b/include/osg/ColorMatrix new file mode 100644 index 000000000..27df0e7c6 --- /dev/null +++ b/include/osg/ColorMatrix @@ -0,0 +1,57 @@ +//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield +//Distributed under the terms of the GNU Library General Public License (LGPL) +//as published by the Free Software Foundation. + +#ifndef OSG_COLORMATRIX +#define OSG_COLORMATRIX 1 + +#include +#include + +namespace osg { + +/** Texture Matrix state class for encapsulating OpenGL texture matrix functionality.*/ +class SG_EXPORT ColorMatrix : public StateAttribute +{ + public : + ColorMatrix( void ); + + META_StateAttribute(ColorMatrix, COLORMATRIX); + + /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ + virtual int compare(const StateAttribute& sa) const + { + // check the types are equal and then create the rhs variable + // used by the COMPARE_StateAttribute_Paramter macro's below. + COMPARE_StateAttribute_Types(ColorMatrix,sa) + + // compare each paramter in turn against the rhs. + COMPARE_StateAttribute_Parameter(_matrix) + + return 0; // passed all the above comparison macro's, must be equal. + } + + /** Set the color matrix */ + inline void setMatrix(const Matrix& matrix) { _matrix = matrix; } + + /** Get the color matrix */ + inline Matrix& getMatrix() { return _matrix; } + + /** Get the const color matrix */ + inline const Matrix& getMatrix() const { return _matrix; } + + /** apply as OpenGL texture matrix.*/ + virtual void apply(State& state) const; + + protected: + + virtual ~ColorMatrix( void ); + + Matrix _matrix; + +}; + +}; + + +#endif diff --git a/include/osg/State b/include/osg/State index 50aac72ef..fbd09fb41 100644 --- a/include/osg/State +++ b/include/osg/State @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -107,11 +108,20 @@ class SG_EXPORT State : public Referenced /** Get the camera */ inline const Camera* getCamera() const { return _camera.get(); } + /** Set the VisualsSettings. Note, nothing is applied, the visual settings are just used + * used in the State object to pass the current visual settings to Drawables + * during rendering. */ + inline void setVisualsSettings(VisualsSettings* vs) { _visualsSettings = vs; } + + /** Get the VisualsSettings */ + inline const VisualsSettings* getVisualsSettings() const { return _visualsSettings.get(); } + private: - unsigned int _contextID; - ref_ptr _frameStamp; - ref_ptr _camera; + unsigned int _contextID; + ref_ptr _frameStamp; + ref_ptr _camera; + ref_ptr _visualsSettings; typedef std::vector ValueVec; diff --git a/include/osg/StateAttribute b/include/osg/StateAttribute index 991bb71f8..df26f6b56 100644 --- a/include/osg/StateAttribute +++ b/include/osg/StateAttribute @@ -98,44 +98,50 @@ class SG_EXPORT StateAttribute : public Object enum Types { TEXTURE =0, - TEXTURE_0 =TEXTURE+0, - TEXTURE_1 =TEXTURE+1, - TEXTURE_2 =TEXTURE+2, - TEXTURE_3 =TEXTURE+3, - MATERIAL =4, - ALPHAFUNC =5, - ANTIALIAS =6, - COLORTABLE =6, - CULLFACE =8, - FOG =9, - FRONTFACE =10, - LIGHT =11, - LIGHT_0 =LIGHT+0, + TEXTURE_0 =TEXTURE, + TEXTURE_1 =TEXTURE_0+1, + TEXTURE_2 =TEXTURE_1+2, + TEXTURE_3 =TEXTURE_2+3, + + MATERIAL =TEXTURE_3+1, + ALPHAFUNC =MATERIAL+1, + ANTIALIAS =ALPHAFUNC+1, + COLORTABLE =ANTIALIAS+1, + CULLFACE =COLORTABLE+1, + FOG =CULLFACE+1, + FRONTFACE =FOG+1, + + LIGHT =FRONTFACE+1, + LIGHT_0 =LIGHT, LIGHT_1 =LIGHT+1, - LIGHT_2 =LIGHT+2, - LIGHT_3 =LIGHT+3, - LIGHT_4 =LIGHT+4, - LIGHT_5 =LIGHT+5, - LIGHT_6 =LIGHT+6, - LIGHT_7 =LIGHT+7, - POINT =18, - POLYGONMODE =19, - POLYGONOFFSET =20, - TEXENV =21, - TEXGEN =22, - TEXMAT =23, - TRANSPARENCY =24, - STENCIL =25, - COLORMASK =26, - DEPTH =27, - VIEWPORT =28, - CLIPPLANE =29, - CLIPPLANE_0 =CLIPPLANE+0, - CLIPPLANE_1 =CLIPPLANE+1, - CLIPPLANE_2 =CLIPPLANE+2, - CLIPPLANE_3 =CLIPPLANE+3, - CLIPPLANE_4 =CLIPPLANE+4, - CLIPPLANE_5 =CLIPPLANE+5 + LIGHT_2 =LIGHT+1, + LIGHT_3 =LIGHT+1, + LIGHT_4 =LIGHT+1, + LIGHT_5 =LIGHT+1, + LIGHT_6 =LIGHT+1, + LIGHT_7 =LIGHT+1, + POINT =LIGHT_7+1, + + POLYGONMODE =POINT+1, + POLYGONOFFSET =POLYGONMODE+1, + TEXENV =POLYGONOFFSET+1, + TEXGEN =TEXENV+1, + TEXMAT =TEXGEN+1, + TRANSPARENCY =TEXMAT+1, + STENCIL =TRANSPARENCY+1, + COLORMASK =STENCIL+1, + DEPTH =COLORMASK+1, + VIEWPORT =DEPTH+1, + + CLIPPLANE =VIEWPORT+1, + CLIPPLANE_0 =CLIPPLANE, + CLIPPLANE_1 =CLIPPLANE_0+1, + CLIPPLANE_2 =CLIPPLANE_1+1, + CLIPPLANE_3 =CLIPPLANE_2+1, + CLIPPLANE_4 =CLIPPLANE_3+1, + CLIPPLANE_5 =CLIPPLANE_4+1, + + COLORMATRIX =CLIPPLANE_5+1 }; StateAttribute() {} diff --git a/include/osg/Viewport b/include/osg/Viewport index babdf0edc..2e8d4e3e2 100644 --- a/include/osg/Viewport +++ b/include/osg/Viewport @@ -59,8 +59,11 @@ class SG_EXPORT Viewport : public StateAttribute inline const int width() const { return _width; } inline const int height() const { return _height; } - /** return the aspcetRatio of the viewport, which is equal to width/height.*/ - inline const float aspectRatio() const { return (float)_width/(float)_height; } + inline const bool valid() const { return _width!=0 && _height!=0; } + + /** Return the aspcetRatio of the viewport, which is equal to width/height. + * If height is zero, the potental division by zero is avoid by simply returning 1.0f.*/ + inline const float aspectRatio() const { if (_height!=0) return (float)_width/(float)_height; else return 1.0f; } virtual void apply(State& state) const; diff --git a/include/osg/VisualsSettings b/include/osg/VisualsSettings new file mode 100644 index 000000000..251709a74 --- /dev/null +++ b/include/osg/VisualsSettings @@ -0,0 +1,115 @@ +//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield +//Distributed under the terms of the GNU Library General Public License (LGPL) +//as published by the Free Software Foundation. + +#ifndef OSG_VISUALSSETTINGS +#define OSG_VISUALSSETTINGS 1 + +#include + +#include +#include + +namespace osg { + +/** VisualsSettings class for encapsulating what visuals are required and + * have been set up, and the status of stereo viewing.*/ +class SG_EXPORT VisualsSettings : public osg::Referenced +{ + + public: + + VisualsSettings() + { + setDefaults(); + readEnvironmentalVariables(); + } + + VisualsSettings(std::vector& commandLine) + { + setDefaults(); + readEnvironmentalVariables(); + readCommandLine(commandLine); + } + + VisualsSettings(const VisualsSettings& vs); + + virtual ~VisualsSettings(); + + VisualsSettings& operator = (const VisualsSettings& vs); + + void merge(const VisualsSettings& vs); + + void setDefaults(); + + void readEnvironmentalVariables(); + + /** read the command line string list, removing any matched control sequences.*/ + void readCommandLine(std::vector& commandLine); + + + + void setStereo(const bool on) { _stereo = on; } + const bool getStereo() const { return _stereo; } + + enum StereoMode + { + QUAD_BUFFER, + ANAGLYPHIC, + HORIZONTAL_SPLIT, + VERTICAL_SPLIT + }; + + void setStereoMode(const StereoMode mode) { _stereoMode = mode; } + const StereoMode getStereoMode() const { return _stereoMode; } + + void setEyeSeperation(const float eyeSeperation) { _eyeSeperation = eyeSeperation; } + const float getEyeSeperation() const { return _eyeSeperation; } + + void setScreenDistance(const float distance) { _screenDistance = distance; } + const float getScreenDistance() const { return _screenDistance; } + + + + void setDoubleBuffer(const bool flag) { _doubleBuffer = flag; } + const bool getDoubleBuffer() const { return _doubleBuffer; } + + + void setRGB(const bool flag) { _RGB = flag; } + const bool getRGB() const { return _RGB; } + + + void setDepthBuffer(const bool flag) { _depthBuffer = flag; } + const bool getDepthBuffer() const { return _depthBuffer; } + + + void setMinimumNumAlphaBits(const unsigned int bits) { _minimumNumberAlphaBits = bits; } + const unsigned int getMinimumNumAlphaBits() const { return _minimumNumberAlphaBits; } + const bool getAlphaBuffer() const { return _minimumNumberAlphaBits!=0; } + + + void setMinimumNumStencilBits(const unsigned int bits) { _minimumNumberStencilBits = bits; } + const unsigned int getMinimumNumStencilBits() const { return _minimumNumberStencilBits; } + const bool getStencilBuffer() const { return _minimumNumberStencilBits!=0; } + + protected: + + void copy(const VisualsSettings& vs); + + bool _stereo; + StereoMode _stereoMode; + float _eyeSeperation; + float _screenDistance; + + bool _doubleBuffer; + bool _RGB; + bool _depthBuffer; + unsigned int _minimumNumberAlphaBits; + unsigned int _minimumNumberStencilBits; + + +}; + +} + +# endif diff --git a/include/osgDB/ReadFile b/include/osgDB/ReadFile index c4631fb01..9975d9e7b 100644 --- a/include/osgDB/ReadFile +++ b/include/osgDB/ReadFile @@ -36,7 +36,11 @@ OSGDB_EXPORT extern osg::Image* readImageFile(const std::string& filename); * The osgDB::Registry is used to load the appropriate ReaderWriter plugin * for the filename extension, and this plugin then handles the request * to read the specified file.*/ -OSGDB_EXPORT extern osg::Node* readNodeFile(const std::string& filename); +OSGDB_EXPORT extern osg::Node* readNodeFile(const std::string& filename); + +/** Read an osg::Node subgraph from files, creating a osg::Group to contain the nodes if more + * than one subgraph has been loaded.*/ +OSGDB_EXPORT extern osg::Node* readNodeFiles(std::vector& commandLine); }; diff --git a/include/osgDB/Registry b/include/osgDB/Registry index 2ee58e882..a358127db 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -17,6 +17,7 @@ namespace osgDB { + /** Registry is a singleton factory which stores the reader/writers which are linked in @@ -38,6 +39,9 @@ class OSGDB_EXPORT Registry static Registry* instance(); + /** read the command line string list, removing any matched control sequences.*/ + void readCommandLine(std::vector& commandLine); + /** register an .fileextension alias to mapExt toExt, the later * should the the extension name of the readerwriter plugin library. * For example to map .tif files to the tiff loader, use @@ -131,6 +135,12 @@ class OSGDB_EXPORT Registry }; +/** read the command line string list into the osgDB::Registry(), removing any matched control sequences.*/ +inline void readCommandLine(std::vector& commandLine) +{ + Registry::instance()->readCommandLine(commandLine); +} + /** Proxy class for automatic registration of DotOsgWrappers with the Registry.*/ class RegisterDotOsgWrapperProxy { diff --git a/include/osgGLUT/Viewer b/include/osgGLUT/Viewer index 510bc2d97..5f89c664e 100644 --- a/include/osgGLUT/Viewer +++ b/include/osgGLUT/Viewer @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -91,6 +92,9 @@ class OSGGLUT_EXPORT Viewer : public osgUtil::GUIActionAdapter virtual void requestContinuousUpdate(bool /*needed*/) {} // continuous update always virtual void requestWarpPointer(int x,int y); + /** read the command line string list, removing any matched control sequences.*/ + void readCommandLine(std::vector& commandLine); + protected: static void displayCB(); @@ -173,8 +177,8 @@ class OSGGLUT_EXPORT Viewer : public osgUtil::GUIActionAdapter osg::Timer_t frameTick(); - osg::ref_ptr _frameStamp; - + osg::ref_ptr _frameStamp; + osg::ref_ptr _visualsSettings; }; diff --git a/include/osgUtil/SceneView b/include/osgUtil/SceneView index 7d1409252..8d90bf41a 100644 --- a/include/osgUtil/SceneView +++ b/include/osgUtil/SceneView @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -76,6 +77,11 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced _viewport->getViewport(x,y,width,height); } + /** Set the VisualsSettings. */ + inline void setVisualsSettings(osg::VisualsSettings* vs) { _visualsSettings = vs; } + + /** Get the VisualsSettings */ + inline const osg::VisualsSettings* getVisualsSettings() const { return _visualsSettings.get(); } /** Set the background color used in glClearColor(). @@ -105,28 +111,11 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced osg::State* getState() { return _state.get(); } const osg::State* getState() const { return _state.get(); } - enum StereoMode - { - MONO, - QUAD_BUFFER_STEREO, - ANAGLYPHIC_STEREO, - HORIZONTAL_SPLIT_STEREO, - VERTICAL_SPLIT_STEREO - }; - - void setStereoMode(const StereoMode mode) { _stereoMode = mode; } - const StereoMode getStereoMode() const { return _stereoMode; } - - void setLeftEyeOffset(const osg::Vec3& pos) { _leftEye = pos; } - void setRightEyeOffset(const osg::Vec3& pos) { _rightEye = pos; } - - void setFocalLength(float length) { _focalLength = length; } - void setScreenDistance(float distance) { _screenDistance = distance; } - void setCamera(osg::Camera* camera) { _camera = camera; } osg::Camera* getCamera() { return _camera.get(); } const osg::Camera* getCamera() const { return _camera.get(); } + void setInitVisitor(osg::NodeVisitor* av) { _initVisitor = av; } osg::NodeVisitor* getInitVisitor() { return _initVisitor.get(); } @@ -229,15 +218,8 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced osg::ref_ptr _globalState; osg::ref_ptr _light; osg::ref_ptr _camera; + osg::ref_ptr _visualsSettings; osg::ref_ptr _state; - - StereoMode _stereoMode; - - osg::Vec3 _leftEye; - osg::Vec3 _rightEye; - - float _focalLength; - float _screenDistance; bool _initCalled; osg::ref_ptr _initVisitor; diff --git a/include/osgUtil/VisualsRequirementsVisitor b/include/osgUtil/VisualsRequirementsVisitor index 5026ab6cd..915bd4c73 100644 --- a/include/osgUtil/VisualsRequirementsVisitor +++ b/include/osgUtil/VisualsRequirementsVisitor @@ -7,7 +7,7 @@ #include #include -#include +#include #include @@ -27,36 +27,13 @@ class OSGUTIL_EXPORT VisualsRequirementsVisitor : public osg::NodeVisitor * alpha and stencil off.*/ VisualsRequirementsVisitor(); + + /** Set the VisualsSettings. */ + inline void setVisualsSettings(osg::VisualsSettings* vs) { _vs = vs; } - void setRequiresDoubleBuffer(const bool flag) { _requiresDoubleBuffer = flag; } - - const bool requiresDoubleBuffer() const { return _requiresDoubleBuffer; } - - - void setRequiresRGB(const bool flag) { _requiresRBG = flag; } - - const bool requiresRGB() const { return _requiresRBG; } - - - void setRequiresDepthBuffer(const bool flag) { _requiresDepthBuffer = flag; } - - const bool requiresDepthBuffer() const { return _requiresDepthBuffer; } - - - void setMinimumNumAlphaBits(const unsigned int bits) { _minimumNumberAlphaBits = bits; } - - const unsigned int getMinimumNumAlphaBits() const { return _minimumNumberAlphaBits; } - - const bool requiresAlphaBuffer() const { return _minimumNumberAlphaBits!=0; } - - - void setMinimumNumStencilBits(const unsigned int bits) { _minimumNumberStencilBits = bits; } - - const unsigned int getMinimumNumStencilBits() const { return _minimumNumberStencilBits; } + /** Get the VisualsSettings */ + inline const osg::VisualsSettings* getVisualsSettings() const { return _vs.get(); } - const bool requiresStencilBuffer() const { return _minimumNumberStencilBits!=0; } - - virtual void applyStateSet(osg::StateSet& stateset); virtual void apply(osg::Node& node); @@ -67,12 +44,8 @@ class OSGUTIL_EXPORT VisualsRequirementsVisitor : public osg::NodeVisitor protected: - bool _requiresDoubleBuffer; - bool _requiresRBG; - bool _requiresDepthBuffer; - unsigned int _minimumNumberAlphaBits; - unsigned int _minimumNumberStencilBits; - + osg::ref_ptr _vs; + }; }; diff --git a/src/Demos/sgv/sgv.cpp b/src/Demos/sgv/sgv.cpp index ed7ceb47c..e980696da 100644 --- a/src/Demos/sgv/sgv.cpp +++ b/src/Demos/sgv/sgv.cpp @@ -1,7 +1,3 @@ -#ifdef USE_MEM_CHECK -#include -#endif - #include #include #include @@ -21,88 +17,9 @@ #include -/* - * Function to read several files (typically one) as specified on the command - * line, and return them in an osg::Node - */ -osg::Node* getNodeFromFiles(int argc,char **argv) -{ - osg::Node *rootnode = new osg::Node; - - int i; - - typedef std::vector NodeList; - NodeList nodeList; - for( i = 1; i < argc; i++ ) - { - - if (argv[i][0]=='-') - { - switch(argv[i][1]) - { - case('l'): - ++i; - if (iloadLibrary(argv[i]); - } - break; - case('e'): - ++i; - if (icreateLibraryNameForExt(argv[i]); - osgDB::Registry::instance()->loadLibrary(libName); - } - break; - } - } else - { - osg::Node *node = osgDB::readNodeFile( argv[i] ); - - if( node != (osg::Node *)0L ) - { - if (node->getName().empty()) node->setName( argv[i] ); - nodeList.push_back(node); - } - } - - } - - if (nodeList.size()==0) - { - osg::notify(osg::WARN) << "No data loaded."<< std::endl; - exit(0); - } - - if (nodeList.size()==1) - { - rootnode = nodeList.front(); - } - else // size >1 - { - osg::Group* group = new osg::Group(); - for(NodeList::iterator itr=nodeList.begin(); - itr!=nodeList.end(); - ++itr) - { - group->addChild(*itr); - } - - rootnode = group; - } - - return rootnode; -} - - int main( int argc, char **argv ) { -#ifdef USE_MEM_CHECK - mtrace(); -#endif - // initialize the GLUT glutInit( &argc, argv ); @@ -125,39 +42,46 @@ int main( int argc, char **argv ) return 0; } - - osg::Timer timer; - osg::Timer_t before_load = timer.tick(); - // comment out right now, but the following allos users to pass option data to + // create the commandline args. + std::vector commandLine; + for(int i=1;isetOptions(new osgDB::ReaderWriter::Options("test options")); - - osg::Node* rootnode = getNodeFromFiles( argc, argv); - osg::Timer_t after_load = timer.tick(); - std::cout << "Time for load = "<setStereoMode(osgUtil::SceneView::ANAGLYPHIC_STEREO); - // register trackball, flight and drive. viewer.registerCameraManipulator(new osgUtil::TrackballManipulator); viewer.registerCameraManipulator(new osgUtil::FlightManipulator); viewer.registerCameraManipulator(new osgUtil::DriveManipulator); + // open the viewer window. viewer.open(); + + // fire up the event loop. viewer.run(); return 0; diff --git a/src/osg/ColorMatrix.cpp b/src/osg/ColorMatrix.cpp new file mode 100644 index 000000000..c7d704ced --- /dev/null +++ b/src/osg/ColorMatrix.cpp @@ -0,0 +1,22 @@ +#include +#include + +using namespace osg; + +ColorMatrix::ColorMatrix() +{ +} + + +ColorMatrix::~ColorMatrix() +{ +} + +void ColorMatrix::apply(State&) const +{ +// std::cout<<"applying matrix"<<_matrix< + +#include + +using namespace osg; + +VisualsSettings::VisualsSettings(const VisualsSettings& vs):Referenced() +{ + copy(vs); +} + +VisualsSettings::~VisualsSettings() +{ +} + +VisualsSettings& VisualsSettings::operator = (const VisualsSettings& vs) +{ + if (this==&vs) return *this; + copy(vs); + return *this; +} + +void VisualsSettings::copy(const VisualsSettings& vs) +{ + _stereoMode = vs._stereoMode; + _eyeSeperation = vs._eyeSeperation; + _screenDistance = vs._screenDistance; + + _doubleBuffer = vs._doubleBuffer; + _RGB = vs._RGB; + _depthBuffer = vs._depthBuffer; + _minimumNumberAlphaBits = vs._minimumNumberAlphaBits; + _minimumNumberStencilBits = vs._minimumNumberStencilBits; +} + +void VisualsSettings::merge(const VisualsSettings& vs) +{ + if (_stereo || vs._stereo) _stereo = true; + + // need to think what to do about merging the stereo mode. + + if (_doubleBuffer || vs._doubleBuffer) _doubleBuffer = true; + if (_RGB || vs._RGB) _RGB = true; + if (_depthBuffer || vs._depthBuffer) _depthBuffer = true; + + if (vs._minimumNumberAlphaBits>_minimumNumberAlphaBits) _minimumNumberAlphaBits = vs._minimumNumberAlphaBits; + if (vs._minimumNumberStencilBits>_minimumNumberStencilBits) _minimumNumberStencilBits = vs._minimumNumberStencilBits; +} + +void VisualsSettings::setDefaults() +{ + _stereo = false; + _stereoMode = ANAGLYPHIC; + _eyeSeperation = 0.05f; + _screenDistance = 1.0f; + + _doubleBuffer = true; + _RGB = true; + _depthBuffer = true; + _minimumNumberAlphaBits = 0; + _minimumNumberStencilBits = 0; +} + +void VisualsSettings::readEnvironmentalVariables() +{ + char *ptr; + if( (ptr = getenv("OSG_STEREO_MODE")) ) + { + if (strcmp(ptr,"QUAD_BUFFER")==0) + { + _stereoMode = QUAD_BUFFER; + } + else + if (strcmp(ptr,"ANAGLYPHIC")==0) + { + _stereoMode = ANAGLYPHIC; + } + else + if (strcmp(ptr,"HORIZONTAL_SPLIT")==0) + { + _stereoMode = HORIZONTAL_SPLIT; + } + else + if (strcmp(ptr,"VERTICAL_SPLIT")==0) + { + _stereoMode = VERTICAL_SPLIT; + } + } + + if( (ptr = getenv("OSG_STEREO")) ) + { + if (strcmp(ptr,"OFF")==0) + { + _stereo = false; + } + else + if (strcmp(ptr,"ON")==0) + { + _stereo = true; + } + } + + if( (ptr = getenv("OSG_EYE_SEPERATION")) ) + { + _eyeSeperation = atof(ptr); + } +} + +void VisualsSettings::readCommandLine(std::vector& commandLine) +{ + + bool found = true; + while (found) + { + found = false; + + // check for stereo based options. + std::vector::iterator itr = commandLine.begin(); + for(;itr!=commandLine.end();++itr) + { + if (*itr=="-stereo") break; + } + + if (itr!=commandLine.end()) + { + + std::cout << "stereo turned on"<::iterator start = itr; + ++itr; + if (itr!=commandLine.end()) + { + if (*itr=="ANAGLYPHIC") { _stereo = true;_stereoMode = ANAGLYPHIC; ++itr; } + else if (*itr=="QUAD_STEREO") { _stereo = true;_stereoMode = QUAD_BUFFER; ++itr; } + else if (*itr=="HORIZONTAL_SPLIT") { _stereo = true;_stereoMode = HORIZONTAL_SPLIT; ++itr; } + else if (*itr=="VERITCAL_SPLIT") { _stereo = true;_stereoMode = VERTICAL_SPLIT; ++itr; } + else if (*itr=="ON") { _stereo = true; ++itr; } + else if (*itr=="OFF") { _stereo = false; ++itr; } + } + + commandLine.erase(start,itr); + found = true; + } + + // check destination alpha + itr = commandLine.begin(); + for(;itr!=commandLine.end();++itr) + { + if (*itr=="-rgba") break; + } + + if (itr!=commandLine.end()) + { + _RGB = true; + _minimumNumberAlphaBits = 1; + commandLine.erase(itr); + found = true; + } + + + // check stencil buffer + itr = commandLine.begin(); + for(;itr!=commandLine.end();++itr) + { + if (*itr=="-stencil") break; + } + + if (itr!=commandLine.end()) + { + _minimumNumberStencilBits = 1; + commandLine.erase(itr); + found = true; + } + + } +} diff --git a/src/osgDB/ReadFile.cpp b/src/osgDB/ReadFile.cpp index 6fe2425de..ff8efa0b1 100644 --- a/src/osgDB/ReadFile.cpp +++ b/src/osgDB/ReadFile.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -34,3 +35,52 @@ Node* osgDB::readNodeFile(const std::string& filename) if (rr.error()) notify(WARN) << rr.message() << std::endl; return NULL; } + +Node* osgDB::readNodeFiles(std::vector& commandLine) +{ + typedef std::vector NodeList; + NodeList nodeList; + + // note currently doesn't delete the loaded files yet... + + for(std::vector::iterator itr=commandLine.begin(); + itr!=commandLine.end(); + ++itr) + { + if ((*itr)[0]!='-') + { + // not an option so assume string is a filename. + osg::Node *node = osgDB::readNodeFile( *itr ); + + if( node != (osg::Node *)0L ) + { + if (node->getName().empty()) node->setName( *itr ); + nodeList.push_back(node); + } + + } + } + + if (nodeList.empty()) + { + return NULL; + } + + if (nodeList.size()==1) + { + return nodeList.front(); + } + else // size >1 + { + osg::Group* group = new osg::Group(); + for(NodeList::iterator itr=nodeList.begin(); + itr!=nodeList.end(); + ++itr) + { + group->addChild(*itr); + } + + return group; + } + +} diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 42c415803..bfe335fbf 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -69,6 +69,58 @@ Registry* Registry::instance() return s_nodeFactory.get(); } +void Registry::readCommandLine(std::vector& commandLine) +{ + + bool found = true; + while (found) + { + found = false; + + // load library option. + std::vector::iterator itr = commandLine.begin(); + for(;itr!=commandLine.end();++itr) + { + if (*itr=="-l") break; + } + + if (itr!=commandLine.end()) + { + std::vector::iterator start = itr; + ++itr; + if (itr!=commandLine.end()) + { + loadLibrary(*itr); + } + commandLine.erase(start,itr); + found = true; + } + + + // load library for extension + itr = commandLine.begin(); + for(;itr!=commandLine.end();++itr) + { + if (*itr=="-e") break; + } + + if (itr!=commandLine.end()) + { + std::vector::iterator start = itr; + ++itr; + if (itr!=commandLine.end()) + { + std::string libName = osgDB::Registry::instance()->createLibraryNameForExt(*itr); + loadLibrary(libName); + } + commandLine.erase(start,itr); + found = true; + } + + + } +} + void Registry::addDotOsgWrapper(DotOsgWrapper* wrapper) { if (wrapper==0L) return; diff --git a/src/osgGLUT/Viewer.cpp b/src/osgGLUT/Viewer.cpp index b4421937d..ec4d53528 100644 --- a/src/osgGLUT/Viewer.cpp +++ b/src/osgGLUT/Viewer.cpp @@ -128,6 +128,7 @@ Viewer::Viewer() _frameStamp = new osg::FrameStamp; + _visualsSettings = new osg::VisualsSettings; } @@ -135,6 +136,11 @@ Viewer::~Viewer() { } +/** read the command line string list, removing any matched control sequences.*/ +void Viewer::readCommandLine(std::vector& commandLine) +{ + _visualsSettings->readCommandLine(commandLine); +} /** * Configure and open the GLUT window for this Viewer @@ -177,6 +183,8 @@ bool Viewer::open() bool needQuadBufferStereo = false; + // do we need quad buffer stereo? + // Set the absolute viewport for each SceneView based on the // relative viewport coordinates given to us for(itr=_viewportList.begin(); @@ -199,9 +207,21 @@ bool Viewer::open() // osg::notify(osg::INFO) << "Handled reshape "<< std::endl; } - if (sceneView->getStereoMode()==osgUtil::SceneView::QUAD_BUFFER_STEREO) needQuadBufferStereo = true; + const osg::VisualsSettings* vs = sceneView->getVisualsSettings(); + if (vs) + { + _visualsSettings->merge(*vs); + } + else + { + // one does not already exist so attach the viewers visualsSettins to the SceneView + sceneView->setVisualsSettings(_visualsSettings.get()); + } } + + if (_visualsSettings->getStereo() && + _visualsSettings->getStereoMode()==osg::VisualsSettings::QUAD_BUFFER) needQuadBufferStereo = true; //glutInit( &argc, argv ); // I moved this into main to avoid passing // argc and argv to the Viewer @@ -211,6 +231,7 @@ bool Viewer::open() // traverse the scene graphs gathering the requirements of the OpenGL buffers. osgUtil::VisualsRequirementsVisitor vrv; + vrv.setVisualsSettings(_visualsSettings.get()); for(itr=_viewportList.begin(); itr!=_viewportList.end(); ++itr) @@ -219,13 +240,13 @@ bool Viewer::open() if (node) node->accept(vrv); } #ifdef _DEBUG - vrv.setMinimumNumStencilBits(8); //gwm 12.8.01 to force stencils available for DC test + _visualsSettings->setMinimumNumStencilBits(8); //gwm 12.8.01 to force stencils available for DC test #endif // set up each render stage to clear the appropriate buffers. GLbitfield clear_mask=0; - if (vrv.requiresRGB()) clear_mask |= GL_COLOR_BUFFER_BIT; - if (vrv.requiresDepthBuffer()) clear_mask |= GL_DEPTH_BUFFER_BIT; - if (vrv.requiresStencilBuffer()) clear_mask |= GL_STENCIL_BUFFER_BIT; + if (_visualsSettings->getRGB()) clear_mask |= GL_COLOR_BUFFER_BIT; + if (_visualsSettings->getDepthBuffer()) clear_mask |= GL_DEPTH_BUFFER_BIT; + if (_visualsSettings->getStencilBuffer()) clear_mask |= GL_STENCIL_BUFFER_BIT; for(itr=_viewportList.begin(); itr!=_viewportList.end(); @@ -238,13 +259,13 @@ bool Viewer::open() // set the GLUT display mode bit mask up to handle it. unsigned int displayMode=0; - if (vrv.requiresDoubleBuffer()) displayMode |= GLUT_DOUBLE; - else displayMode |= GLUT_SINGLE; - if (vrv.requiresRGB()) displayMode |= GLUT_RGB; - if (vrv.requiresDepthBuffer()) displayMode |= GLUT_DEPTH; - if (vrv.requiresAlphaBuffer()) displayMode |= GLUT_ALPHA; - if (vrv.requiresStencilBuffer()) displayMode |= GLUT_STENCIL; - if (needQuadBufferStereo) displayMode |= GLUT_STEREO; + if (_visualsSettings->getDoubleBuffer()) displayMode |= GLUT_DOUBLE; + else displayMode |= GLUT_SINGLE; + if (_visualsSettings->getRGB()) displayMode |= GLUT_RGB; + if (_visualsSettings->getDepthBuffer()) displayMode |= GLUT_DEPTH; + if (_visualsSettings->getAlphaBuffer()) displayMode |= GLUT_ALPHA; + if (_visualsSettings->getStencilBuffer()) displayMode |= GLUT_STENCIL; + if (needQuadBufferStereo) displayMode |= GLUT_STEREO; // and we'll add in multisample so that on systems like Onyx's can // go ahead and use there loverly anti-aliasing. This is ignored diff --git a/src/osgPlugins/osg/ColorMatrix.cpp b/src/osgPlugins/osg/ColorMatrix.cpp new file mode 100644 index 000000000..eaf522012 --- /dev/null +++ b/src/osgPlugins/osg/ColorMatrix.cpp @@ -0,0 +1,67 @@ +#include + +#include +#include +#include + +using namespace osg; +using namespace osgDB; + +// forward declare functions to use later. +bool ColorMatrix_readLocalData(Object& obj, Input& fr); +bool ColorMatrix_writeLocalData(const Object& obj, Output& fw); + +// register the read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_ColorMatrixProxy +( + new osg::ColorMatrix, + "ColorMatrix", + "Object StateAttribute ColorMatrix", + &ColorMatrix_readLocalData, + &ColorMatrix_writeLocalData +); + + +bool ColorMatrix_readLocalData(Object& obj, Input& fr) +{ + bool iteratorAdvanced = false; + + ColorMatrix& colorMatrix = static_cast(obj); + + bool matched = true; + for(int k=0;k<16 && matched;++k) + { + matched = fr[k].isFloat(); + } + if (matched) + { + + Matrix& matrix = colorMatrix.getMatrix(); + + int k=0; + for(int i=0;i<4;++i) + { + for(int j=0;j<4;++j) + { + fr[k].getFloat(matrix(i,j)); + k++; + } + } + fr += 16; + iteratorAdvanced = true; + } + + return iteratorAdvanced; +} + + +bool ColorMatrix_writeLocalData(const Object& obj, Output& fw) +{ + const ColorMatrix& colorMatrix = static_cast(obj); + const Matrix& matrix = colorMatrix.getMatrix(); + fw.indent() << matrix(0,0) << " " << matrix(0,1) << " " << matrix(0,2) << " " << matrix(0,3) << std::endl; + fw.indent() << matrix(1,0) << " " << matrix(1,1) << " " << matrix(1,2) << " " << matrix(1,3) << std::endl; + fw.indent() << matrix(2,0) << " " << matrix(2,1) << " " << matrix(2,2) << " " << matrix(2,3) << std::endl; + fw.indent() << matrix(3,0) << " " << matrix(3,1) << " " << matrix(3,2) << " " << matrix(3,3) << std::endl; + return true; +} diff --git a/src/osgPlugins/osg/Makefile b/src/osgPlugins/osg/Makefile index f34335896..6ec4c8bb3 100644 --- a/src/osgPlugins/osg/Makefile +++ b/src/osgPlugins/osg/Makefile @@ -6,6 +6,7 @@ C++FILES = \ Billboard.cpp\ ClipPlane.cpp\ ColorMask.cpp\ + ColorMatrix.cpp\ CullFace.cpp\ Depth.cpp\ Drawable.cpp\ diff --git a/src/osgPlugins/osg/TexMat.cpp b/src/osgPlugins/osg/TexMat.cpp index 2caf2a64b..afebcc7a2 100644 --- a/src/osgPlugins/osg/TexMat.cpp +++ b/src/osgPlugins/osg/TexMat.cpp @@ -1,8 +1,8 @@ -#include "osg/TexMat" +#include -#include "osgDB/Registry" -#include "osgDB/Input" -#include "osgDB/Output" +#include +#include +#include using namespace osg; using namespace osgDB; diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index 48e0aeecb..c65006c44 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -52,15 +53,6 @@ void SceneView::setDefaults() _state = new State; _camera = new Camera; - - _stereoMode = MONO; - - _leftEye.set(-0.03f,0.0f,0.0f); - _rightEye.set(0.03f,0.0f,0.0f); - - _focalLength = 1.0f; - _screenDistance = 1.0f; - _rendergraph = new RenderGraph; _renderStage = new RenderStage; @@ -143,7 +135,7 @@ void SceneView::app() void SceneView::cull() { - if (!_sceneData) return; + if (!_sceneData || !_viewport->valid()) return; if (!_initCalled) init(); @@ -276,7 +268,7 @@ void SceneView::cull() void SceneView::draw() { - if (!_sceneData) return; + if (!_sceneData || !_viewport->valid()) return; if (!_state) { @@ -290,6 +282,7 @@ void SceneView::draw() _state->reset(); _state->setFrameStamp(_frameStamp.get()); + _state->setVisualsSettings(_visualsSettings.get()); // note, to support multi-pipe systems the deletion of OpenGL display list // and texture objects is deferred until the OpenGL context is the correct @@ -299,67 +292,84 @@ void SceneView::draw() osg::Texture::flushDeletedTextureObjects(_state->getContextID()); RenderLeaf* previous = NULL; - - switch(getStereoMode()) - { - case(MONO): - { - _renderStage->draw(*_state,previous); - } - break; - case(QUAD_BUFFER_STEREO): - { - osg::ref_ptr left_camera = new osg::Camera(*_camera); - osg::ref_ptr right_camera = new osg::Camera(*_camera); - float iod = 0.05f; - - left_camera->adjustEyeOffsetForStereo(osg::Vec3(-iod*0.5,0.0f,0.0f),_screenDistance); - right_camera->adjustEyeOffsetForStereo(osg::Vec3(iod*0.5,0.0f,0.0f),_screenDistance); - - glDrawBuffer(GL_BACK_LEFT); - _renderStage->setCamera(left_camera.get()); - _renderStage->draw(*_state,previous); - - - glDrawBuffer(GL_BACK_RIGHT); - _renderStage->setCamera(right_camera.get()); - _renderStage->_stageDrawnThisFrame = false; - _renderStage->draw(*_state,previous); - } - break; - case(ANAGLYPHIC_STEREO): - { - osg::ref_ptr left_camera = new osg::Camera(*_camera); - osg::ref_ptr right_camera = new osg::Camera(*_camera); - float iod = 0.05f; - - left_camera->adjustEyeOffsetForStereo(osg::Vec3(-iod*0.5,0.0f,0.0f),_screenDistance); - right_camera->adjustEyeOffsetForStereo(osg::Vec3(iod*0.5,0.0f,0.0f),_screenDistance); - - osg::ColorMask* red = new osg::ColorMask; - osg::ColorMask* green = new osg::ColorMask; - - red->setMask(true,false,false,true); - _renderStage->setColorMask(red); - _renderStage->setCamera(left_camera.get()); - _renderStage->draw(*_state,previous); - - green->setMask(false,true,true,true); - _renderStage->setColorMask(green); - _renderStage->_stageDrawnThisFrame = false; - _renderStage->setCamera(right_camera.get()); - _renderStage->draw(*_state,previous); - - } - break; - default: - { - osg::notify(osg::NOTICE)<<"Warning: stereo camera mode not implemented yet."<< std::endl; - _renderStage->draw(*_state,previous); - } - break; - } + if (_visualsSettings.valid() && _visualsSettings->getStereo()) + { + + switch(_visualsSettings->getStereoMode()) + { + case(osg::VisualsSettings::QUAD_BUFFER): + { + osg::ref_ptr left_camera = new osg::Camera(*_camera); + osg::ref_ptr right_camera = new osg::Camera(*_camera); + + float iod = _visualsSettings->getEyeSeperation(); + float screenDistance = _visualsSettings->getEyeSeperation(); + + left_camera->adjustEyeOffsetForStereo(osg::Vec3(-iod*0.5,0.0f,0.0f),screenDistance); + right_camera->adjustEyeOffsetForStereo(osg::Vec3(iod*0.5,0.0f,0.0f),screenDistance); + + glDrawBuffer(GL_BACK_LEFT); + _renderStage->setCamera(left_camera.get()); + _renderStage->draw(*_state,previous); + + + glDrawBuffer(GL_BACK_RIGHT); + _renderStage->setCamera(right_camera.get()); + _renderStage->_stageDrawnThisFrame = false; + _renderStage->draw(*_state,previous); + } + break; + case(osg::VisualsSettings::ANAGLYPHIC): + { + osg::ref_ptr left_camera = new osg::Camera(*_camera); + osg::ref_ptr right_camera = new osg::Camera(*_camera); + + float iod = _visualsSettings->getEyeSeperation(); + float screenDistance = _visualsSettings->getScreenDistance(); + + left_camera->adjustEyeOffsetForStereo(osg::Vec3(-iod*0.5,0.0f,0.0f),screenDistance); + right_camera->adjustEyeOffsetForStereo(osg::Vec3(iod*0.5,0.0f,0.0f),screenDistance); + + + osg::ColorMatrix* cm = new osg::ColorMatrix; + cm->setMatrix(osg::Matrix(0.3,0.3,0.3,0.0, + 0.6,0.6,0.6,0.0, + 0.1,0.1,0.1,0.0, + 0.0,0.0,0.0,1.0)); + + _globalState->setAttribute(cm); + + osg::ColorMask* red = new osg::ColorMask; + osg::ColorMask* green = new osg::ColorMask; + + red->setMask(true,false,false,true); + _renderStage->setColorMask(red); + _renderStage->setCamera(left_camera.get()); + _renderStage->draw(*_state,previous); + + green->setMask(false,true,true,true); + _renderStage->setColorMask(green); + _renderStage->_stageDrawnThisFrame = false; + _renderStage->setCamera(right_camera.get()); + _renderStage->draw(*_state,previous); + + } + break; + default: + { + osg::notify(osg::NOTICE)<<"Warning: stereo camera mode not implemented yet."<< std::endl; + _renderStage->draw(*_state,previous); + } + break; + } + } + else + { + // bog standard draw. + _renderStage->draw(*_state,previous); + } + GLenum errorNo = glGetError(); if (errorNo!=GL_NO_ERROR) { diff --git a/src/osgUtil/VisualsRequirementsVisitor.cpp b/src/osgUtil/VisualsRequirementsVisitor.cpp index 50d555716..f7a069b4e 100644 --- a/src/osgUtil/VisualsRequirementsVisitor.cpp +++ b/src/osgUtil/VisualsRequirementsVisitor.cpp @@ -16,25 +16,29 @@ using namespace osgUtil; VisualsRequirementsVisitor::VisualsRequirementsVisitor() { setTraversalMode(NodeVisitor::TRAVERSE_ALL_CHILDREN); - _requiresDoubleBuffer = true; - _requiresRBG = true; - _requiresDepthBuffer = true; - _minimumNumberAlphaBits = 0; - _minimumNumberStencilBits = 0; - } void VisualsRequirementsVisitor::applyStateSet(StateSet& stateset) { + if (!_vs) _vs = new osg::VisualsSettings; + + unsigned int min = 0; // assume stencil not needed by this stateset. + if (stateset.getMode(GL_STENCIL_TEST) & StateAttribute::ON) { - _minimumNumberStencilBits = 1; + min = 1; // number stencil bits we need at least. } if (stateset.getAttribute(StateAttribute::STENCIL)) { - _minimumNumberStencilBits = 1; + min = 1; // number stencil bits we need at least. } + + if (min>_vs->getMinimumNumStencilBits()) + { + // only update if new minimum exceeds previous minimum. + _vs->setMinimumNumStencilBits(min); + } } void VisualsRequirementsVisitor::apply(Node& node) @@ -59,6 +63,14 @@ void VisualsRequirementsVisitor::apply(Geode& geode) void VisualsRequirementsVisitor::apply(Impostor& impostor) { - _minimumNumberAlphaBits = 1; + if (!_vs) _vs = new osg::VisualsSettings; + + unsigned int min = 1; // number alpha bits we need at least. + if (min>_vs->getMinimumNumAlphaBits()) + { + // only update if new minimum exceeds previous minimum. + _vs->setMinimumNumAlphaBits(min); + } + apply((Node&)impostor); }