diff --git a/include/osg/DisplaySettings b/include/osg/DisplaySettings index 4ab5bd18d..8e1f5c2df 100644 --- a/include/osg/DisplaySettings +++ b/include/osg/DisplaySettings @@ -76,6 +76,30 @@ class SG_EXPORT DisplaySettings : public osg::Referenced void setScreenDistance(const float distance) { _screenDistance = distance; } const float getScreenDistance() const { return _screenDistance; } + enum SplitStereoHorizontalEyeMapping + { + LEFT_EYE_LEFT_VIEWPORT, + LEFT_EYE_RIGHT_VIEWPORT + }; + + void setSplitStereoHorizontalEyeMapping(SplitStereoHorizontalEyeMapping m) { _splitStereoHorizontalEyeMapping = m; } + SplitStereoHorizontalEyeMapping getSplitStereoHorizontalEyeMapping() const { return _splitStereoHorizontalEyeMapping; } + + void setSplitStereoHorizontalSeperation(const int s) { _splitStereoHorizontalSeperation = s; } + const int getSplitStereoHorizontalSeperation() const { return _splitStereoHorizontalSeperation; } + + enum SplitStereoVerticalEyeMapping + { + LEFT_EYE_TOP_VIEWPORT, + LEFT_EYE_BOTTOM_VIEWPORT, + }; + + void setSplitStereoVerticalEyeMapping(SplitStereoVerticalEyeMapping m) { _splitStereoVerticalEyeMapping = m; } + SplitStereoVerticalEyeMapping getSplitStereoVerticalEyeMapping() const { return _splitStereoVerticalEyeMapping; } + + void setSplitStereoVerticalSeperation(const int s) { _splitStereoVerticalSeperation = s; } + const int getSplitStereoVerticalSeperation() const { return _splitStereoVerticalSeperation; } + void setScreenHeight(const float height) { _screenHeight = height; } const float getScreenHeight() const { return _screenHeight; } @@ -111,19 +135,24 @@ class SG_EXPORT DisplaySettings : public osg::Referenced void copy(const DisplaySettings& vs); - bool _stereo; - StereoMode _stereoMode; - float _eyeSeperation; - float _screenDistance; - float _screenHeight; - - bool _doubleBuffer; - bool _RGB; - bool _depthBuffer; - unsigned int _minimumNumberAlphaBits; - unsigned int _minimumNumberStencilBits; + bool _stereo; + StereoMode _stereoMode; + float _eyeSeperation; + float _screenDistance; + float _screenHeight; - int _maxNumOfGraphicsContexts; + SplitStereoHorizontalEyeMapping _splitStereoHorizontalEyeMapping; + int _splitStereoHorizontalSeperation; + SplitStereoVerticalEyeMapping _splitStereoVerticalEyeMapping; + int _splitStereoVerticalSeperation; + + bool _doubleBuffer; + bool _RGB; + bool _depthBuffer; + unsigned int _minimumNumberAlphaBits; + unsigned int _minimumNumberStencilBits; + + int _maxNumOfGraphicsContexts; }; diff --git a/include/osg/Image b/include/osg/Image index 0e25c536f..292115473 100644 --- a/include/osg/Image +++ b/include/osg/Image @@ -110,9 +110,9 @@ class SG_EXPORT Image : public Object /** Ensure image dimensions are a power of two. * Mip Mapped texture require the image dimensions to be - * power of two. - */ - void ensureDimensionsArePowerOfTwo(); + * power of two and are within the maxiumum texture size for + * the host machine.*/ + void ensureValidSizeForTexturing(); /** Dirty the image, which increments the modified flag, to force osg::Texture to reload the image.*/ inline void dirty() { ++_modifiedTag; } diff --git a/src/osg/DisplaySettings.cpp b/src/osg/DisplaySettings.cpp index c110b6d09..d99d73a29 100644 --- a/src/osg/DisplaySettings.cpp +++ b/src/osg/DisplaySettings.cpp @@ -49,6 +49,12 @@ void DisplaySettings::copy(const DisplaySettings& vs) _screenDistance = vs._screenDistance; _screenHeight = vs._screenHeight; + _splitStereoHorizontalEyeMapping = vs._splitStereoHorizontalEyeMapping; + _splitStereoHorizontalSeperation = vs._splitStereoHorizontalSeperation; + + _splitStereoVerticalEyeMapping = vs._splitStereoVerticalEyeMapping; + _splitStereoVerticalSeperation = vs._splitStereoVerticalSeperation; + _doubleBuffer = vs._doubleBuffer; _RGB = vs._RGB; _depthBuffer = vs._depthBuffer; @@ -80,6 +86,12 @@ void DisplaySettings::setDefaults() _screenDistance = 0.5f; _screenHeight = 0.26f; + _splitStereoHorizontalEyeMapping = LEFT_EYE_LEFT_VIEWPORT; + _splitStereoHorizontalSeperation = 42; + + _splitStereoVerticalEyeMapping = LEFT_EYE_TOP_VIEWPORT; + _splitStereoVerticalSeperation = 42; + _doubleBuffer = true; _RGB = true; _depthBuffer = true; @@ -147,6 +159,43 @@ void DisplaySettings::readEnvironmentalVariables() _screenHeight = atof(ptr); } + 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; + } + } + + if( (ptr = getenv("OSG_SPLIT_STEREO_HORIZONTAL_SEPERATION")) != 0) + { + _splitStereoHorizontalSeperation = atoi(ptr); + } + + + 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; + } + } + + if( (ptr = getenv("OSG_SPLIT_STEREO_VERTICAL_SEPERATION")) != 0) + { + _splitStereoVerticalSeperation = atoi(ptr); + } + if( (ptr = getenv("OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS")) != 0) { _maxNumOfGraphicsContexts = atoi(ptr); diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index 751912b8c..55aeaa541 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -307,7 +307,7 @@ void Image::scaleImage(const int s,const int t,const int r) } -void Image::ensureDimensionsArePowerOfTwo() +void Image::ensureValidSizeForTexturing() { int new_s = _s; int new_t = _t; diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index ffff252d3..8889b342d 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -331,7 +331,7 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const if (_subloadMode == OFF) - image->ensureDimensionsArePowerOfTwo(); + image->ensureValidSizeForTexturing(); glPixelStorei(GL_UNPACK_ALIGNMENT,image->packing()); diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index 358cb1df6..c5c0e467b 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -440,43 +440,68 @@ void SceneView::draw() break; case(osg::DisplaySettings::HORIZONTAL_SPLIT): { - int left_half = _viewport->width()/2; - int right_half = _viewport->width()-left_half; - + int seperation = _displaySettings->getSplitStereoHorizontalSeperation(); + + int left_half_width = (_viewport->width()-seperation)/2; + int right_half_begin = (_viewport->width()+seperation)/2; + int right_half_width = _viewport->width()-right_half_begin; - // draw left eye. osg::ref_ptr viewportLeft = osgNew osg::Viewport; - viewportLeft->setViewport(_viewport->x(),_viewport->y(),left_half,_viewport->height()); - _renderStageLeft->setViewport(viewportLeft.get()); - drawStage(_renderStageLeft.get()); + viewportLeft->setViewport(_viewport->x(),_viewport->y(),left_half_width,_viewport->height()); - // draw right eye. osg::ref_ptr viewportRight = osgNew osg::Viewport; - viewportRight->setViewport(_viewport->x()+left_half,_viewport->y(),right_half,_viewport->height()); - _renderStageRight->setViewport(viewportRight.get()); - drawStage(_renderStageRight.get()); + viewportRight->setViewport(_viewport->x()+right_half_begin,_viewport->y(),right_half_width,_viewport->height()); + + if (_displaySettings->getSplitStereoHorizontalEyeMapping()==osg::DisplaySettings::LEFT_EYE_LEFT_VIEWPORT) + { + _renderStageLeft->setViewport(viewportLeft.get()); + drawStage(_renderStageLeft.get()); + + _renderStageRight->setViewport(viewportRight.get()); + drawStage(_renderStageRight.get()); + } + else + { + _renderStageLeft->setViewport(viewportRight.get()); + drawStage(_renderStageLeft.get()); + + _renderStageRight->setViewport(viewportLeft.get()); + drawStage(_renderStageRight.get()); + } } break; case(osg::DisplaySettings::VERTICAL_SPLIT): { - int bottom_half = _viewport->height()/2; - int top_half = _viewport->height()-bottom_half; - // draw left eye. - // assume left eye at top, this could be implementation dependant... - osg::ref_ptr viewportLeft = osgNew osg::Viewport; - viewportLeft->setViewport(_viewport->x(),_viewport->y()+bottom_half,_viewport->width(),top_half); - _renderStageLeft->setViewport(viewportLeft.get()); - drawStage(_renderStageLeft.get()); + int seperation = _displaySettings->getSplitStereoVerticalSeperation(); - // draw right eye. - // assume right eye at top, this could be implementation dependant... - osg::ref_ptr viewportRight = osgNew osg::Viewport; - viewportRight->setViewport(_viewport->x(),_viewport->y(),_viewport->width(),bottom_half); - _renderStageRight->setViewport(viewportRight.get()); - drawStage(_renderStageRight.get()); + int bottom_half_height = (_viewport->height()-seperation)/2; + int top_half_begin = (_viewport->height()+seperation)/2; + int top_half_height = _viewport->height()-top_half_begin; + osg::ref_ptr viewportTop = osgNew osg::Viewport; + viewportTop->setViewport(_viewport->x(),_viewport->y()+top_half_begin,_viewport->width(),top_half_height); + + osg::ref_ptr viewportBottom = osgNew osg::Viewport; + viewportBottom->setViewport(_viewport->x(),_viewport->y(),_viewport->width(),bottom_half_height); + + if (_displaySettings->getSplitStereoVerticalEyeMapping()==osg::DisplaySettings::LEFT_EYE_TOP_VIEWPORT) + { + _renderStageLeft->setViewport(viewportTop.get()); + drawStage(_renderStageLeft.get()); + + _renderStageRight->setViewport(viewportBottom.get()); + drawStage(_renderStageRight.get()); + } + else + { + _renderStageLeft->setViewport(viewportBottom.get()); + drawStage(_renderStageLeft.get()); + + _renderStageRight->setViewport(viewportTop.get()); + drawStage(_renderStageRight.get()); + } } break; default: