2003-01-22 00:45:36 +08:00
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 .
*/
2001-12-22 06:48:19 +08:00
# include <osg/DisplaySettings>
2003-02-19 05:10:42 +08:00
# include <osg/ArgumentParser>
2003-02-19 00:36:42 +08:00
# include <osg/ApplicationUsage>
2003-01-10 17:25:42 +08:00
# include <osg/ref_ptr>
2001-12-19 08:38:23 +08:00
# include <algorithm>
using namespace osg ;
2002-02-23 01:12:10 +08:00
using namespace std ;
2002-02-28 08:11:31 +08:00
DisplaySettings * DisplaySettings : : instance ( )
{
2003-01-10 17:25:42 +08:00
static ref_ptr < DisplaySettings > s_displaySettings = new DisplaySettings ;
2002-02-28 08:11:31 +08:00
return s_displaySettings . get ( ) ;
}
2001-12-22 06:48:19 +08:00
DisplaySettings : : DisplaySettings ( const DisplaySettings & vs ) : Referenced ( )
2001-12-19 08:38:23 +08:00
{
copy ( vs ) ;
}
2001-12-22 06:48:19 +08:00
DisplaySettings : : ~ DisplaySettings ( )
2001-12-19 08:38:23 +08:00
{
}
2002-02-28 08:11:31 +08:00
DisplaySettings & DisplaySettings : : operator = ( const DisplaySettings & vs )
2001-12-19 08:38:23 +08:00
{
if ( this = = & vs ) return * this ;
copy ( vs ) ;
return * this ;
}
2001-12-22 06:48:19 +08:00
void DisplaySettings : : copy ( const DisplaySettings & vs )
2001-12-19 08:38:23 +08:00
{
_stereoMode = vs . _stereoMode ;
2002-08-29 11:22:27 +08:00
_eyeSeparation = vs . _eyeSeparation ;
2001-12-19 08:38:23 +08:00
_screenDistance = vs . _screenDistance ;
2001-12-22 06:48:19 +08:00
_screenHeight = vs . _screenHeight ;
2001-12-19 08:38:23 +08:00
2002-04-15 06:21:59 +08:00
_splitStereoHorizontalEyeMapping = vs . _splitStereoHorizontalEyeMapping ;
2002-08-29 11:22:27 +08:00
_splitStereoHorizontalSeparation = vs . _splitStereoHorizontalSeparation ;
2002-04-15 06:21:59 +08:00
_splitStereoVerticalEyeMapping = vs . _splitStereoVerticalEyeMapping ;
2002-08-29 11:22:27 +08:00
_splitStereoVerticalSeparation = vs . _splitStereoVerticalSeparation ;
2002-04-15 06:21:59 +08:00
2001-12-19 08:38:23 +08:00
_doubleBuffer = vs . _doubleBuffer ;
_RGB = vs . _RGB ;
_depthBuffer = vs . _depthBuffer ;
_minimumNumberAlphaBits = vs . _minimumNumberAlphaBits ;
_minimumNumberStencilBits = vs . _minimumNumberStencilBits ;
2002-02-28 08:11:31 +08:00
_maxNumOfGraphicsContexts = vs . _maxNumOfGraphicsContexts ;
2001-12-19 08:38:23 +08:00
}
2001-12-22 06:48:19 +08:00
void DisplaySettings : : merge ( const DisplaySettings & vs )
2001-12-19 08:38:23 +08:00
{
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 ;
}
2001-12-22 06:48:19 +08:00
void DisplaySettings : : setDefaults ( )
2001-12-19 08:38:23 +08:00
{
_stereo = false ;
_stereoMode = ANAGLYPHIC ;
2002-08-29 11:22:27 +08:00
_eyeSeparation = 0.05f ;
2001-12-22 06:48:19 +08:00
_screenDistance = 0.5f ;
_screenHeight = 0.26f ;
2001-12-19 08:38:23 +08:00
2002-04-15 06:21:59 +08:00
_splitStereoHorizontalEyeMapping = LEFT_EYE_LEFT_VIEWPORT ;
2002-08-29 11:22:27 +08:00
_splitStereoHorizontalSeparation = 42 ;
2002-04-15 06:21:59 +08:00
_splitStereoVerticalEyeMapping = LEFT_EYE_TOP_VIEWPORT ;
2002-08-29 11:22:27 +08:00
_splitStereoVerticalSeparation = 42 ;
2002-04-15 06:21:59 +08:00
2001-12-19 08:38:23 +08:00
_doubleBuffer = true ;
_RGB = true ;
_depthBuffer = true ;
_minimumNumberAlphaBits = 0 ;
_minimumNumberStencilBits = 0 ;
2002-02-28 08:11:31 +08:00
# ifdef __sgi
_maxNumOfGraphicsContexts = 4 ;
# else
_maxNumOfGraphicsContexts = 1 ;
# endif
2001-12-19 08:38:23 +08:00
}
2003-02-19 00:36:42 +08:00
ApplicationUsageProxy e0 ( ApplicationUsage : : ENVIRONMENTAL_VARIABLE , " OSG_STEREO_MODE <mode> " , " QUAD_BUFFER | ANAGLYPHIC | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE " ) ;
ApplicationUsageProxy e1 ( ApplicationUsage : : ENVIRONMENTAL_VARIABLE , " OSG_STEREO <mode> " , " OFF | ON " ) ;
ApplicationUsageProxy e2 ( ApplicationUsage : : ENVIRONMENTAL_VARIABLE , " OSG_EYE_SEPARATION <float> " , " physical distance between eyes " ) ;
ApplicationUsageProxy e3 ( ApplicationUsage : : ENVIRONMENTAL_VARIABLE , " OSG_SCREEN_DISTANCE <float> " , " physical distance between eyes and screen " ) ;
ApplicationUsageProxy e4 ( ApplicationUsage : : ENVIRONMENTAL_VARIABLE , " OSG_SCREEN_HEIGHT <float> " , " physical screen height " ) ;
ApplicationUsageProxy e5 ( ApplicationUsage : : ENVIRONMENTAL_VARIABLE , " OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING <mode> " , " LEFT_EYE_LEFT_VIEWPORT | LEFT_EYE_RIGHT_VIEWPORT " ) ;
ApplicationUsageProxy e8 ( ApplicationUsage : : ENVIRONMENTAL_VARIABLE , " OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION <float> " , " number of pixels between viewports " ) ;
ApplicationUsageProxy e9 ( ApplicationUsage : : ENVIRONMENTAL_VARIABLE , " OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING <mode> " , " LEFT_EYE_TOP_VIEWPORT | LEFT_EYE_BOTTOM_VIEWPORT " ) ;
ApplicationUsageProxy e11 ( ApplicationUsage : : ENVIRONMENTAL_VARIABLE , " OSG_SPLIT_STEREO_VERTICAL_SEPARATION <float> " , " number of pixels between viewports " ) ;
ApplicationUsageProxy e12 ( ApplicationUsage : : ENVIRONMENTAL_VARIABLE , " OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS <int> " , " maximum number of graphics contexts to be used with applications. " ) ;
2001-12-22 06:48:19 +08:00
void DisplaySettings : : readEnvironmentalVariables ( )
2001-12-19 08:38:23 +08:00
{
char * ptr ;
2002-01-30 23:02:56 +08:00
if ( ( ptr = getenv ( " OSG_STEREO_MODE " ) ) ! = 0 )
2001-12-19 08:38:23 +08:00
{
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 ;
}
2002-11-12 18:22:38 +08:00
else
if ( strcmp ( ptr , " LEFT_EYE " ) = = 0 )
{
_stereoMode = LEFT_EYE ;
}
else
if ( strcmp ( ptr , " RIGHT_EYE " ) = = 0 )
{
_stereoMode = RIGHT_EYE ;
}
2001-12-19 08:38:23 +08:00
}
2002-01-30 23:02:56 +08:00
if ( ( ptr = getenv ( " OSG_STEREO " ) ) ! = 0 )
2001-12-19 08:38:23 +08:00
{
if ( strcmp ( ptr , " OFF " ) = = 0 )
{
_stereo = false ;
}
else
if ( strcmp ( ptr , " ON " ) = = 0 )
{
_stereo = true ;
}
}
2002-08-29 11:22:27 +08:00
if ( ( ptr = getenv ( " OSG_EYE_SEPARATION " ) ) ! = 0 )
2001-12-19 08:38:23 +08:00
{
2002-08-29 11:22:27 +08:00
_eyeSeparation = atof ( ptr ) ;
2001-12-19 08:38:23 +08:00
}
2001-12-19 18:29:18 +08:00
2002-01-30 23:02:56 +08:00
if ( ( ptr = getenv ( " OSG_SCREEN_DISTANCE " ) ) ! = 0 )
2001-12-19 18:29:18 +08:00
{
_screenDistance = atof ( ptr ) ;
}
2001-12-22 06:48:19 +08:00
2002-01-30 23:02:56 +08:00
if ( ( ptr = getenv ( " OSG_SCREEN_HEIGHT " ) ) ! = 0 )
2001-12-22 06:48:19 +08:00
{
_screenHeight = atof ( ptr ) ;
}
2002-02-28 08:11:31 +08:00
2002-04-15 06:21:59 +08:00
if ( ( ptr = getenv ( " OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING " ) ) ! = 0 )
{
if ( strcmp ( ptr , " LEFT_EYE_LEFT_VIEWPORT " ) = = 0 )
{
_splitStereoHorizontalEyeMapping = LEFT_EYE_LEFT_VIEWPORT ;
}
else
if ( strcmp ( ptr , " LEFT_EYE_RIGHT_VIEWPORT " ) = = 0 )
{
_splitStereoHorizontalEyeMapping = LEFT_EYE_RIGHT_VIEWPORT ;
}
}
2002-08-29 11:22:27 +08:00
if ( ( ptr = getenv ( " OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION " ) ) ! = 0 )
2002-04-15 06:21:59 +08:00
{
2002-08-29 11:22:27 +08:00
_splitStereoHorizontalSeparation = atoi ( ptr ) ;
2002-04-15 06:21:59 +08:00
}
if ( ( ptr = getenv ( " OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING " ) ) ! = 0 )
{
if ( strcmp ( ptr , " LEFT_EYE_TOP_VIEWPORT " ) = = 0 )
{
_splitStereoVerticalEyeMapping = LEFT_EYE_TOP_VIEWPORT ;
}
else
if ( strcmp ( ptr , " LEFT_EYE_BOTTOM_VIEWPORT " ) = = 0 )
{
_splitStereoVerticalEyeMapping = LEFT_EYE_BOTTOM_VIEWPORT ;
}
}
2002-08-29 11:22:27 +08:00
if ( ( ptr = getenv ( " OSG_SPLIT_STEREO_VERTICAL_SEPARATION " ) ) ! = 0 )
2002-04-15 06:21:59 +08:00
{
2002-08-29 11:22:27 +08:00
_splitStereoVerticalSeparation = atoi ( ptr ) ;
2002-04-15 06:21:59 +08:00
}
2002-02-28 08:11:31 +08:00
if ( ( ptr = getenv ( " OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS " ) ) ! = 0 )
{
2002-03-24 05:30:32 +08:00
_maxNumOfGraphicsContexts = atoi ( ptr ) ;
2002-02-28 08:11:31 +08:00
}
2001-12-19 08:38:23 +08:00
}
2001-12-22 06:48:19 +08:00
void DisplaySettings : : readCommandLine ( std : : vector < std : : string > & commandLine )
2001-12-19 08:38:23 +08:00
{
bool found = true ;
while ( found )
{
found = false ;
// check for stereo based options.
std : : vector < std : : string > : : iterator itr = commandLine . begin ( ) ;
for ( ; itr ! = commandLine . end ( ) ; + + itr )
{
if ( * itr = = " -stereo " ) break ;
}
if ( itr ! = commandLine . end ( ) )
{
_stereo = true ;
std : : vector < std : : string > : : iterator start = itr ;
+ + itr ;
if ( itr ! = commandLine . end ( ) )
{
if ( * itr = = " ANAGLYPHIC " ) { _stereo = true ; _stereoMode = ANAGLYPHIC ; + + itr ; }
2001-12-19 18:29:18 +08:00
else if ( * itr = = " QUAD_BUFFER " ) { _stereo = true ; _stereoMode = QUAD_BUFFER ; + + itr ; }
2001-12-19 08:38:23 +08:00
else if ( * itr = = " HORIZONTAL_SPLIT " ) { _stereo = true ; _stereoMode = HORIZONTAL_SPLIT ; + + itr ; }
2001-12-19 18:29:18 +08:00
else if ( * itr = = " VERTICAL_SPLIT " ) { _stereo = true ; _stereoMode = VERTICAL_SPLIT ; + + itr ; }
2002-11-12 18:22:38 +08:00
else if ( * itr = = " LEFT_EYE " ) { _stereo = true ; _stereoMode = LEFT_EYE ; + + itr ; }
else if ( * itr = = " RIGHT_EYE " ) { _stereo = true ; _stereoMode = RIGHT_EYE ; + + itr ; }
2001-12-19 08:38:23 +08:00
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 ;
}
}
}
2003-02-19 00:36:42 +08:00
void DisplaySettings : : readCommandLine ( ArgumentParser & parser )
{
int pos ;
while ( ( pos = parser . find ( " -stereo " ) ) ! = 0 )
{
if ( parser . match ( pos + 1 , " ANAGLYPHIC " ) ) { parser . remove ( pos , 2 ) ; _stereo = true ; _stereoMode = ANAGLYPHIC ; }
else if ( parser . match ( pos + 1 , " QUAD_BUFFER " ) ) { parser . remove ( pos , 2 ) ; _stereo = true ; _stereoMode = QUAD_BUFFER ; }
else if ( parser . match ( pos + 1 , " HORIZONTAL_SPLIT " ) ) { parser . remove ( pos , 2 ) ; _stereo = true ; _stereoMode = HORIZONTAL_SPLIT ; }
else if ( parser . match ( pos + 1 , " VERTICAL_SPLIT " ) ) { parser . remove ( pos , 2 ) ; _stereo = true ; _stereoMode = VERTICAL_SPLIT ; }
else if ( parser . match ( pos + 1 , " LEFT_EYE " ) ) { parser . remove ( pos , 2 ) ; _stereo = true ; _stereoMode = LEFT_EYE ; }
else if ( parser . match ( pos + 1 , " RIGHT_EYE " ) ) { parser . remove ( pos , 2 ) ; _stereo = true ; _stereoMode = RIGHT_EYE ; }
else if ( parser . match ( pos + 1 , " ON " ) ) { parser . remove ( pos , 2 ) ; _stereo = true ; }
else if ( parser . match ( pos + 1 , " OFF " ) ) { parser . remove ( pos , 2 ) ; _stereo = false ; }
else { parser . remove ( pos ) ; _stereo = true ; }
}
while ( parser . read ( " -rgba " ) )
{
_RGB = true ;
_minimumNumberAlphaBits = 1 ;
}
while ( parser . read ( " -stencil " ) )
{
_minimumNumberStencilBits = 1 ;
}
}