Preperation for adding stereo support direclty into osgViewer.

This commit is contained in:
Robert Osfield 2013-04-15 14:21:32 +00:00
parent bc288d23dc
commit 34a6b38983
7 changed files with 239 additions and 131 deletions

View File

@ -15,6 +15,7 @@
#define OSG_DisplaySettings 1 #define OSG_DisplaySettings 1
#include <osg/Referenced> #include <osg/Referenced>
#include <osg/Matrixd>
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <string> #include <string>
@ -184,6 +185,11 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
void setSerializeDrawDispatch(bool serializeDrawDispatch) { _serializeDrawDispatch = serializeDrawDispatch; } void setSerializeDrawDispatch(bool serializeDrawDispatch) { _serializeDrawDispatch = serializeDrawDispatch; }
bool getSerializeDrawDispatch() const { return _serializeDrawDispatch; } bool getSerializeDrawDispatch() const { return _serializeDrawDispatch; }
void setUseSceneViewForStereoHint(bool hint) { _useSceneViewForStereoHint = hint; }
bool getUseSceneViewForStereoHint() const { return _useSceneViewForStereoHint; }
/** Set the hint for the total number of threads in the DatbasePager set up, inclusive of the number of http dedicated threads.*/ /** Set the hint for the total number of threads in the DatbasePager set up, inclusive of the number of http dedicated threads.*/
void setNumOfDatabaseThreadsHint(unsigned int numThreads) { _numDatabaseThreadsHint = numThreads; } void setNumOfDatabaseThreadsHint(unsigned int numThreads) { _numDatabaseThreadsHint = numThreads; }
@ -278,6 +284,22 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
/** Get the hint of the profile mask to use in when creating graphic contexts.*/ /** Get the hint of the profile mask to use in when creating graphic contexts.*/
unsigned int getGLContextProfileMask() const { return _glContextProfileMask; } unsigned int getGLContextProfileMask() const { return _glContextProfileMask; }
/** helper function for computing the left eye projection matrix.*/
virtual osg::Matrixd computeLeftEyeProjectionImplementation(const osg::Matrixd& projection) const;
/** helper function for computing the left eye view matrix.*/
virtual osg::Matrixd computeLeftEyeViewImplementation(const osg::Matrixd& view, double eyeSeperationScale=1.0) const;
/** helper function for computing the right eye view matrix.*/
virtual osg::Matrixd computeRightEyeProjectionImplementation(const osg::Matrixd& projection) const;
/** helper function for computing the right eye view matrix.*/
virtual osg::Matrixd computeRightEyeViewImplementation(const osg::Matrixd& view, double eyeSeperationScale=1.0) const;
protected: protected:
virtual ~DisplaySettings(); virtual ~DisplaySettings();
@ -313,6 +335,7 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
bool _compileContextsHint; bool _compileContextsHint;
bool _serializeDrawDispatch; bool _serializeDrawDispatch;
bool _useSceneViewForStereoHint;
unsigned int _numDatabaseThreadsHint; unsigned int _numDatabaseThreadsHint;
unsigned int _numHttpDatabaseThreadsHint; unsigned int _numHttpDatabaseThreadsHint;

View File

@ -64,6 +64,18 @@ class OSG_EXPORT Viewport : public StateAttribute
return 0; // passed all the above comparison macros, must be equal. return 0; // passed all the above comparison macros, must be equal.
} }
Viewport& operator = (const Viewport& rhs)
{
if (&rhs==this) return *this;
_x = rhs._x;
_y = rhs._y;
_width = rhs._width;
_height = rhs._height;
return *this;
}
inline void setViewport(value_type x,value_type y,value_type width,value_type height) inline void setViewport(value_type x,value_type y,value_type width,value_type height)
{ {
_x = x; _x = x;

View File

@ -406,8 +406,6 @@ class OSGUTIL_EXPORT SceneView : public osg::Object, public osg::CullSettings
inline const osg::FrameStamp* getFrameStamp() const { return _frameStamp.get(); } inline const osg::FrameStamp* getFrameStamp() const { return _frameStamp.get(); }
inline osg::Matrixd computeLeftEyeProjection(const osg::Matrixd& projection) const inline osg::Matrixd computeLeftEyeProjection(const osg::Matrixd& projection) const
{ {
if (_computeStereoMatricesCallback.valid()) return _computeStereoMatricesCallback->computeLeftEyeProjection(projection); if (_computeStereoMatricesCallback.valid()) return _computeStereoMatricesCallback->computeLeftEyeProjection(projection);
@ -432,12 +430,19 @@ class OSGUTIL_EXPORT SceneView : public osg::Object, public osg::CullSettings
else return computeRightEyeViewImplementation(view); else return computeRightEyeViewImplementation(view);
} }
/** helper function for computing the left eye projection matrix.*/
virtual osg::Matrixd computeLeftEyeProjectionImplementation(const osg::Matrixd& projection) const; virtual osg::Matrixd computeLeftEyeProjectionImplementation(const osg::Matrixd& projection) const;
/** helper function for computing the left eye view matrix.*/
virtual osg::Matrixd computeLeftEyeViewImplementation(const osg::Matrixd& view) const; virtual osg::Matrixd computeLeftEyeViewImplementation(const osg::Matrixd& view) const;
/** helper function for computing the right eye view matrix.*/
virtual osg::Matrixd computeRightEyeProjectionImplementation(const osg::Matrixd& projection) const; virtual osg::Matrixd computeRightEyeProjectionImplementation(const osg::Matrixd& projection) const;
/** helper function for computing the right eye view matrix.*/
virtual osg::Matrixd computeRightEyeViewImplementation(const osg::Matrixd& view) const; virtual osg::Matrixd computeRightEyeViewImplementation(const osg::Matrixd& view) const;
/** Inherit the local cull settings variable from a specified CullSettings object, according to the inheritance mask.*/ /** Inherit the local cull settings variable from a specified CullSettings object, according to the inheritance mask.*/
virtual void inheritCullSettings(const osg::CullSettings& settings) { inheritCullSettings(settings, _inheritanceMask); } virtual void inheritCullSettings(const osg::CullSettings& settings) { inheritCullSettings(settings, _inheritanceMask); }

View File

@ -86,6 +86,7 @@ class OSGVIEWER_EXPORT Renderer : public osg::GraphicsOperation
bool _done; bool _done;
bool _graphicsThreadDoesCull; bool _graphicsThreadDoesCull;
bool _compileOnNextDraw; bool _compileOnNextDraw;
bool _serializeDraw;
osg::ref_ptr<osgUtil::SceneView> _sceneView[2]; osg::ref_ptr<osgUtil::SceneView> _sceneView[2];

View File

@ -79,6 +79,7 @@ void DisplaySettings::setDisplaySettings(const DisplaySettings& vs)
_compileContextsHint = vs._compileContextsHint; _compileContextsHint = vs._compileContextsHint;
_serializeDrawDispatch = vs._serializeDrawDispatch; _serializeDrawDispatch = vs._serializeDrawDispatch;
_useSceneViewForStereoHint = vs._useSceneViewForStereoHint;
_numDatabaseThreadsHint = vs._numDatabaseThreadsHint; _numDatabaseThreadsHint = vs._numDatabaseThreadsHint;
_numHttpDatabaseThreadsHint = vs._numHttpDatabaseThreadsHint; _numHttpDatabaseThreadsHint = vs._numHttpDatabaseThreadsHint;
@ -113,6 +114,7 @@ void DisplaySettings::merge(const DisplaySettings& vs)
if (vs._compileContextsHint) _compileContextsHint = vs._compileContextsHint; if (vs._compileContextsHint) _compileContextsHint = vs._compileContextsHint;
if (vs._serializeDrawDispatch) _serializeDrawDispatch = vs._serializeDrawDispatch; if (vs._serializeDrawDispatch) _serializeDrawDispatch = vs._serializeDrawDispatch;
if (vs._useSceneViewForStereoHint) _useSceneViewForStereoHint = vs._useSceneViewForStereoHint;
if (vs._numDatabaseThreadsHint>_numDatabaseThreadsHint) _numDatabaseThreadsHint = vs._numDatabaseThreadsHint; if (vs._numDatabaseThreadsHint>_numDatabaseThreadsHint) _numDatabaseThreadsHint = vs._numDatabaseThreadsHint;
if (vs._numHttpDatabaseThreadsHint>_numHttpDatabaseThreadsHint) _numHttpDatabaseThreadsHint = vs._numHttpDatabaseThreadsHint; if (vs._numHttpDatabaseThreadsHint>_numHttpDatabaseThreadsHint) _numHttpDatabaseThreadsHint = vs._numHttpDatabaseThreadsHint;
@ -170,6 +172,7 @@ void DisplaySettings::setDefaults()
_compileContextsHint = false; _compileContextsHint = false;
_serializeDrawDispatch = true; _serializeDrawDispatch = true;
_useSceneViewForStereoHint = true;
_numDatabaseThreadsHint = 2; _numDatabaseThreadsHint = 2;
_numHttpDatabaseThreadsHint = 1; _numHttpDatabaseThreadsHint = 1;
@ -251,39 +254,42 @@ static ApplicationUsageProxy DisplaySetting_e14(ApplicationUsage::ENVIRONMENTAL_
"OSG_SERIALIZE_DRAW_DISPATCH <mode>", "OSG_SERIALIZE_DRAW_DISPATCH <mode>",
"OFF | ON Disable/enable the use of a mutex to serialize the draw dispatch when there are multiple graphics threads."); "OFF | ON Disable/enable the use of a mutex to serialize the draw dispatch when there are multiple graphics threads.");
static ApplicationUsageProxy DisplaySetting_e15(ApplicationUsage::ENVIRONMENTAL_VARIABLE, static ApplicationUsageProxy DisplaySetting_e15(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_USE_SCENEVIEW_FOR_STEREO <mode>",
"OFF | ON Disable/enable the hint to use osgUtil::SceneView to implement stereo when required..");
static ApplicationUsageProxy DisplaySetting_e16(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_NUM_DATABASE_THREADS <int>", "OSG_NUM_DATABASE_THREADS <int>",
"Set the hint for the total number of threads to set up in the DatabasePager."); "Set the hint for the total number of threads to set up in the DatabasePager.");
static ApplicationUsageProxy DisplaySetting_e16(ApplicationUsage::ENVIRONMENTAL_VARIABLE, static ApplicationUsageProxy DisplaySetting_e17(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_NUM_HTTP_DATABASE_THREADS <int>", "OSG_NUM_HTTP_DATABASE_THREADS <int>",
"Set the hint for the total number of threads dedicated to http requests to set up in the DatabasePager."); "Set the hint for the total number of threads dedicated to http requests to set up in the DatabasePager.");
static ApplicationUsageProxy DisplaySetting_e17(ApplicationUsage::ENVIRONMENTAL_VARIABLE, static ApplicationUsageProxy DisplaySetting_e18(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_MULTI_SAMPLES <int>", "OSG_MULTI_SAMPLES <int>",
"Set the hint for the number of samples to use when multi-sampling."); "Set the hint for the number of samples to use when multi-sampling.");
static ApplicationUsageProxy DisplaySetting_e18(ApplicationUsage::ENVIRONMENTAL_VARIABLE, static ApplicationUsageProxy DisplaySetting_e19(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_TEXTURE_POOL_SIZE <int>", "OSG_TEXTURE_POOL_SIZE <int>",
"Set the hint for the size of the texture pool to manage."); "Set the hint for the size of the texture pool to manage.");
static ApplicationUsageProxy DisplaySetting_e19(ApplicationUsage::ENVIRONMENTAL_VARIABLE, static ApplicationUsageProxy DisplaySetting_e20(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_BUFFER_OBJECT_POOL_SIZE <int>", "OSG_BUFFER_OBJECT_POOL_SIZE <int>",
"Set the hint for the size of the vertex buffer object pool to manage."); "Set the hint for the size of the vertex buffer object pool to manage.");
static ApplicationUsageProxy DisplaySetting_e20(ApplicationUsage::ENVIRONMENTAL_VARIABLE, static ApplicationUsageProxy DisplaySetting_e21(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_FBO_POOL_SIZE <int>", "OSG_FBO_POOL_SIZE <int>",
"Set the hint for the size of the frame buffer object pool to manage."); "Set the hint for the size of the frame buffer object pool to manage.");
static ApplicationUsageProxy DisplaySetting_e21(ApplicationUsage::ENVIRONMENTAL_VARIABLE, static ApplicationUsageProxy DisplaySetting_e22(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_IMPLICIT_BUFFER_ATTACHMENT_RENDER_MASK", "OSG_IMPLICIT_BUFFER_ATTACHMENT_RENDER_MASK",
"OFF | DEFAULT | [~]COLOR | [~]DEPTH | [~]STENCIL. Substitute missing buffer attachments for render FBO."); "OFF | DEFAULT | [~]COLOR | [~]DEPTH | [~]STENCIL. Substitute missing buffer attachments for render FBO.");
static ApplicationUsageProxy DisplaySetting_e22(ApplicationUsage::ENVIRONMENTAL_VARIABLE, static ApplicationUsageProxy DisplaySetting_e23(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_IMPLICIT_BUFFER_ATTACHMENT_RESOLVE_MASK", "OSG_IMPLICIT_BUFFER_ATTACHMENT_RESOLVE_MASK",
"OFF | DEFAULT | [~]COLOR | [~]DEPTH | [~]STENCIL. Substitute missing buffer attachments for resolve FBO."); "OFF | DEFAULT | [~]COLOR | [~]DEPTH | [~]STENCIL. Substitute missing buffer attachments for resolve FBO.");
static ApplicationUsageProxy DisplaySetting_e23(ApplicationUsage::ENVIRONMENTAL_VARIABLE, static ApplicationUsageProxy DisplaySetting_e24(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_GL_CONTEXT_VERSION <major.minor>", "OSG_GL_CONTEXT_VERSION <major.minor>",
"Set the hint for the GL version to create contexts for."); "Set the hint for the GL version to create contexts for.");
static ApplicationUsageProxy DisplaySetting_e24(ApplicationUsage::ENVIRONMENTAL_VARIABLE, static ApplicationUsageProxy DisplaySetting_e25(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_GL_CONTEXT_FLAGS <uint>", "OSG_GL_CONTEXT_FLAGS <uint>",
"Set the hint for the GL context flags to use when creating contexts."); "Set the hint for the GL context flags to use when creating contexts.");
static ApplicationUsageProxy DisplaySetting_e25(ApplicationUsage::ENVIRONMENTAL_VARIABLE, static ApplicationUsageProxy DisplaySetting_e26(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_GL_CONTEXT_PROFILE_MASK <uint>", "OSG_GL_CONTEXT_PROFILE_MASK <uint>",
"Set the hint for the GL context profile mask to use when creating contexts."); "Set the hint for the GL context profile mask to use when creating contexts.");
static ApplicationUsageProxy DisplaySetting_e26(ApplicationUsage::ENVIRONMENTAL_VARIABLE, static ApplicationUsageProxy DisplaySetting_e27(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_SWAP_METHOD <method>", "OSG_SWAP_METHOD <method>",
"DEFAULT | EXCHANGE | COPY | UNDEFINED. Select preferred swap method."); "DEFAULT | EXCHANGE | COPY | UNDEFINED. Select preferred swap method.");
@ -469,6 +475,19 @@ void DisplaySettings::readEnvironmentalVariables()
} }
} }
if( (ptr = getenv("OSG_USE_SCENEVIEW_FOR_STEREO")) != 0)
{
if (strcmp(ptr,"OFF")==0)
{
_useSceneViewForStereoHint = false;
}
else
if (strcmp(ptr,"ON")==0)
{
_useSceneViewForStereoHint = true;
}
}
if( (ptr = getenv("OSG_NUM_DATABASE_THREADS")) != 0) if( (ptr = getenv("OSG_NUM_DATABASE_THREADS")) != 0)
{ {
_numDatabaseThreadsHint = atoi(ptr); _numDatabaseThreadsHint = atoi(ptr);
@ -708,3 +727,113 @@ void DisplaySettings::readCommandLine(ArgumentParser& arguments)
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Helper funciotns for computing projection and view matrices of left and right eyes
//
osg::Matrixd DisplaySettings::computeLeftEyeProjectionImplementation(const osg::Matrixd& projection) const
{
double iod = getEyeSeparation();
double sd = getScreenDistance();
double scale_x = 1.0;
double scale_y = 1.0;
if (getSplitStereoAutoAdjustAspectRatio())
{
switch(getStereoMode())
{
case(HORIZONTAL_SPLIT):
scale_x = 2.0;
break;
case(VERTICAL_SPLIT):
scale_y = 2.0;
break;
default:
break;
}
}
if (getDisplayType()==HEAD_MOUNTED_DISPLAY)
{
// head mounted display has the same projection matrix for left and right eyes.
return osg::Matrixd::scale(scale_x,scale_y,1.0) *
projection;
}
else
{
// all other display types assume working like a projected power wall
// need to shjear projection matrix to account for asymetric frustum due to eye offset.
return osg::Matrixd(1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
iod/(2.0*sd),0.0,1.0,0.0,
0.0,0.0,0.0,1.0) *
osg::Matrixd::scale(scale_x,scale_y,1.0) *
projection;
}
}
osg::Matrixd DisplaySettings::computeLeftEyeViewImplementation(const osg::Matrixd& view, double eyeSeperationScale) const
{
double iod = getEyeSeparation();
double es = 0.5f*iod*eyeSeperationScale;
return view *
osg::Matrixd(1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
es,0.0,0.0,1.0);
}
osg::Matrixd DisplaySettings::computeRightEyeProjectionImplementation(const osg::Matrixd& projection) const
{
double iod = getEyeSeparation();
double sd = getScreenDistance();
double scale_x = 1.0;
double scale_y = 1.0;
if (getSplitStereoAutoAdjustAspectRatio())
{
switch(getStereoMode())
{
case(HORIZONTAL_SPLIT):
scale_x = 2.0;
break;
case(VERTICAL_SPLIT):
scale_y = 2.0;
break;
default:
break;
}
}
if (getDisplayType()==HEAD_MOUNTED_DISPLAY)
{
// head mounted display has the same projection matrix for left and right eyes.
return osg::Matrixd::scale(scale_x,scale_y,1.0) *
projection;
}
else
{
// all other display types assume working like a projected power wall
// need to shjear projection matrix to account for asymetric frustum due to eye offset.
return osg::Matrixd(1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
-iod/(2.0*sd),0.0,1.0,0.0,
0.0,0.0,0.0,1.0) *
osg::Matrixd::scale(scale_x,scale_y,1.0) *
projection;
}
}
osg::Matrixd DisplaySettings::computeRightEyeViewImplementation(const osg::Matrixd& view, double eyeSeperationScale) const
{
double iod = getEyeSeparation();
double es = 0.5*iod*eyeSeperationScale;
return view *
osg::Matrixd(1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
-es,0.0,0.0,1.0);
}

View File

@ -429,48 +429,15 @@ void SceneView::updateUniforms()
osg::Matrixd SceneView::computeLeftEyeProjectionImplementation(const osg::Matrixd& projection) const osg::Matrixd SceneView::computeLeftEyeProjectionImplementation(const osg::Matrixd& projection) const
{ {
double iod = _displaySettings->getEyeSeparation(); return _displaySettings.valid() ? _displaySettings->computeLeftEyeProjectionImplementation(projection) : projection;
double sd = _displaySettings->getScreenDistance();
double scale_x = 1.0;
double scale_y = 1.0;
if (_displaySettings->getSplitStereoAutoAdjustAspectRatio())
{
switch(_displaySettings->getStereoMode())
{
case(osg::DisplaySettings::HORIZONTAL_SPLIT):
scale_x = 2.0;
break;
case(osg::DisplaySettings::VERTICAL_SPLIT):
scale_y = 2.0;
break;
default:
break;
}
}
if (_displaySettings->getDisplayType()==osg::DisplaySettings::HEAD_MOUNTED_DISPLAY)
{
// head mounted display has the same projection matrix for left and right eyes.
return osg::Matrixd::scale(scale_x,scale_y,1.0) *
projection;
}
else
{
// all other display types assume working like a projected power wall
// need to shjear projection matrix to account for asymetric frustum due to eye offset.
return osg::Matrixd(1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
iod/(2.0*sd),0.0,1.0,0.0,
0.0,0.0,0.0,1.0) *
osg::Matrixd::scale(scale_x,scale_y,1.0) *
projection;
}
} }
osg::Matrixd SceneView::computeLeftEyeViewImplementation(const osg::Matrixd& view) const osg::Matrixd SceneView::computeLeftEyeViewImplementation(const osg::Matrixd& view) const
{ {
double fusionDistance = _displaySettings->getScreenDistance(); if (!_displaySettings) return view;
double sd = _displaySettings->getScreenDistance();
double fusionDistance = sd;
switch(_fusionDistanceMode) switch(_fusionDistanceMode)
{ {
case(USE_FUSION_DISTANCE_VALUE): case(USE_FUSION_DISTANCE_VALUE):
@ -480,62 +447,22 @@ osg::Matrixd SceneView::computeLeftEyeViewImplementation(const osg::Matrixd& vie
fusionDistance *= _fusionDistanceValue; fusionDistance *= _fusionDistanceValue;
break; break;
} }
double eyeScale = (fusionDistance/sd);
double iod = _displaySettings->getEyeSeparation(); return _displaySettings->computeLeftEyeViewImplementation(view, eyeScale);
double sd = _displaySettings->getScreenDistance();
double es = 0.5f*iod*(fusionDistance/sd);
return view *
osg::Matrixd(1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
es,0.0,0.0,1.0);
} }
osg::Matrixd SceneView::computeRightEyeProjectionImplementation(const osg::Matrixd& projection) const osg::Matrixd SceneView::computeRightEyeProjectionImplementation(const osg::Matrixd& projection) const
{ {
double iod = _displaySettings->getEyeSeparation(); return _displaySettings.valid() ? _displaySettings->computeRightEyeProjectionImplementation(projection) : projection;
double sd = _displaySettings->getScreenDistance();
double scale_x = 1.0;
double scale_y = 1.0;
if (_displaySettings->getSplitStereoAutoAdjustAspectRatio())
{
switch(_displaySettings->getStereoMode())
{
case(osg::DisplaySettings::HORIZONTAL_SPLIT):
scale_x = 2.0;
break;
case(osg::DisplaySettings::VERTICAL_SPLIT):
scale_y = 2.0;
break;
default:
break;
}
}
if (_displaySettings->getDisplayType()==osg::DisplaySettings::HEAD_MOUNTED_DISPLAY)
{
// head mounted display has the same projection matrix for left and right eyes.
return osg::Matrixd::scale(scale_x,scale_y,1.0) *
projection;
}
else
{
// all other display types assume working like a projected power wall
// need to shjear projection matrix to account for asymetric frustum due to eye offset.
return osg::Matrixd(1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
-iod/(2.0*sd),0.0,1.0,0.0,
0.0,0.0,0.0,1.0) *
osg::Matrixd::scale(scale_x,scale_y,1.0) *
projection;
}
} }
osg::Matrixd SceneView::computeRightEyeViewImplementation(const osg::Matrixd& view) const osg::Matrixd SceneView::computeRightEyeViewImplementation(const osg::Matrixd& view) const
{ {
float fusionDistance = _displaySettings->getScreenDistance(); if (!_displaySettings) return view;
double sd = _displaySettings->getScreenDistance();
double fusionDistance = sd;
switch(_fusionDistanceMode) switch(_fusionDistanceMode)
{ {
case(USE_FUSION_DISTANCE_VALUE): case(USE_FUSION_DISTANCE_VALUE):
@ -545,16 +472,9 @@ osg::Matrixd SceneView::computeRightEyeViewImplementation(const osg::Matrixd& vi
fusionDistance *= _fusionDistanceValue; fusionDistance *= _fusionDistanceValue;
break; break;
} }
double eyeScale = (fusionDistance/sd);
double iod = _displaySettings->getEyeSeparation(); return _displaySettings->computeRightEyeViewImplementation(view, eyeScale);
double sd = _displaySettings->getScreenDistance();
double es = 0.5*iod*(fusionDistance/sd);
return view *
osg::Matrixd(1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
-es,0.0,0.0,1.0);
} }
void SceneView::computeLeftEyeViewport(const osg::Viewport *viewport) void SceneView::computeLeftEyeViewport(const osg::Viewport *viewport)
@ -563,6 +483,12 @@ void SceneView::computeLeftEyeViewport(const osg::Viewport *viewport)
if(!_viewportLeft.valid()) _viewportLeft = new osg::Viewport; if(!_viewportLeft.valid()) _viewportLeft = new osg::Viewport;
if (!_displaySettings)
{
(*_viewportLeft) = *viewport;
return;
}
switch(_displaySettings->getStereoMode()) switch(_displaySettings->getStereoMode())
{ {
@ -603,7 +529,7 @@ void SceneView::computeLeftEyeViewport(const osg::Viewport *viewport)
break; break;
default: default:
_viewportLeft->setViewport(viewport->x(),viewport->y(),viewport->width(),viewport->height()); *(_viewportLeft) = *viewport;
break; break;
} }
} }
@ -612,8 +538,14 @@ void SceneView::computeRightEyeViewport(const osg::Viewport *viewport)
{ {
if(!viewport) return; if(!viewport) return;
if(!_viewportRight.valid()) _viewportRight = new osg::Viewport; if(!_viewportRight) _viewportRight = new osg::Viewport;
if (!_displaySettings)
{
(*_viewportRight) = *viewport;
return;
}
switch(_displaySettings->getStereoMode()) switch(_displaySettings->getStereoMode())
{ {
case(osg::DisplaySettings::HORIZONTAL_SPLIT): case(osg::DisplaySettings::HORIZONTAL_SPLIT):
@ -653,7 +585,7 @@ void SceneView::computeRightEyeViewport(const osg::Viewport *viewport)
break; break;
default: default:
_viewportRight->setViewport(viewport->x(),viewport->y(),viewport->width(),viewport->height()); *(_viewportRight) = *viewport;
break; break;
} }
} }
@ -740,20 +672,12 @@ void SceneView::cull()
_renderInfo.setState(new osg::State); _renderInfo.setState(new osg::State);
} }
osg::State* state = _renderInfo.getState();
if (!_localStateSet) if (!_localStateSet)
{ {
_localStateSet = new osg::StateSet; _localStateSet = new osg::StateSet;
} }
// 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());
if (!_cullVisitor) if (!_cullVisitor)
{ {
OSG_INFO << "Warning: no valid osgUtil::SceneView:: attached, creating a default CullVisitor automatically."<< std::endl; OSG_INFO << "Warning: no valid osgUtil::SceneView:: attached, creating a default CullVisitor automatically."<< std::endl;
@ -1043,6 +967,16 @@ void SceneView::draw()
if (_camera->getNodeMask()==0) return; if (_camera->getNodeMask()==0) return;
osg::State* state = _renderInfo.getState(); osg::State* state = _renderInfo.getState();
// 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());
if (_displaySettings.valid())
{
state->setDisplaySettings(_displaySettings.get());
}
state->initializeExtensionProcs(); state->initializeExtensionProcs();
osg::Texture::TextureObjectManager* tom = osg::Texture::getTextureObjectManager(state->getContextID()).get(); osg::Texture::TextureObjectManager* tom = osg::Texture::getTextureObjectManager(state->getContextID()).get();

View File

@ -34,7 +34,6 @@ using namespace osgViewer;
//#define DEBUG_MESSAGE OSG_NOTICE //#define DEBUG_MESSAGE OSG_NOTICE
#define DEBUG_MESSAGE OSG_DEBUG #define DEBUG_MESSAGE OSG_DEBUG
OpenGLQuerySupport::OpenGLQuerySupport(): OpenGLQuerySupport::OpenGLQuerySupport():
_extensions(0) _extensions(0)
{ {
@ -357,6 +356,7 @@ Renderer::Renderer(osg::Camera* camera):
_done(false), _done(false),
_graphicsThreadDoesCull(true), _graphicsThreadDoesCull(true),
_compileOnNextDraw(true), _compileOnNextDraw(true),
_serializeDraw(false),
_initialized(false), _initialized(false),
_startTick(0) _startTick(0)
{ {
@ -388,6 +388,8 @@ Renderer::Renderer(osg::Camera* camera):
osg::DisplaySettings* ds = _camera->getDisplaySettings() ? _camera->getDisplaySettings() : osg::DisplaySettings* ds = _camera->getDisplaySettings() ? _camera->getDisplaySettings() :
((view && view->getDisplaySettings()) ? view->getDisplaySettings() : osg::DisplaySettings::instance().get()); ((view && view->getDisplaySettings()) ? view->getDisplaySettings() : osg::DisplaySettings::instance().get());
_serializeDraw = ds ? ds->getSerializeDrawDispatch() : false;
unsigned int sceneViewOptions = osgUtil::SceneView::HEADLIGHT; unsigned int sceneViewOptions = osgUtil::SceneView::HEADLIGHT;
if (view) if (view)
{ {
@ -410,9 +412,12 @@ Renderer::Renderer(osg::Camera* camera):
_sceneView[0]->setDefaults(sceneViewOptions); _sceneView[0]->setDefaults(sceneViewOptions);
_sceneView[1]->setDefaults(sceneViewOptions); _sceneView[1]->setDefaults(sceneViewOptions);
_sceneView[0]->setDisplaySettings(ds); if (ds->getUseSceneViewForStereoHint())
_sceneView[1]->setDisplaySettings(ds); {
_sceneView[0]->setDisplaySettings(ds);
_sceneView[1]->setDisplaySettings(ds);
}
_sceneView[0]->setCamera(_camera.get(), false); _sceneView[0]->setCamera(_camera.get(), false);
_sceneView[1]->setCamera(_camera.get(), false); _sceneView[1]->setCamera(_camera.get(), false);
@ -520,7 +525,10 @@ void Renderer::updateSceneView(osgUtil::SceneView* sceneView)
osg::DisplaySettings* ds = _camera->getDisplaySettings() ? _camera->getDisplaySettings() : osg::DisplaySettings* ds = _camera->getDisplaySettings() ? _camera->getDisplaySettings() :
((view &&view->getDisplaySettings()) ? view->getDisplaySettings() : osg::DisplaySettings::instance().get()); ((view &&view->getDisplaySettings()) ? view->getDisplaySettings() : osg::DisplaySettings::instance().get());
sceneView->setDisplaySettings(ds); if (ds->getUseSceneViewForStereoHint())
{
sceneView->setDisplaySettings(ds);
}
if (view) if (view)
{ {
@ -691,7 +699,7 @@ void Renderer::draw()
osg::Stats* stats = sceneView->getCamera()->getStats(); osg::Stats* stats = sceneView->getCamera()->getStats();
osg::State* state = sceneView->getState(); osg::State* state = sceneView->getState();
unsigned int frameNumber = state->getFrameStamp()->getFrameNumber(); unsigned int frameNumber = sceneView->getFrameStamp()->getFrameNumber();
if (!_initialized) if (!_initialized)
{ {
@ -723,9 +731,7 @@ void Renderer::draw()
osg::Timer_t beforeDrawTick; osg::Timer_t beforeDrawTick;
bool serializeDraw = sceneView->getDisplaySettings()->getSerializeDrawDispatch(); if (_serializeDraw)
if (serializeDraw)
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_drawSerializerMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_drawSerializerMutex);
beforeDrawTick = osg::Timer::instance()->tick(); beforeDrawTick = osg::Timer::instance()->tick();
@ -794,7 +800,7 @@ void Renderer::cull_draw()
osg::Stats* stats = sceneView->getCamera()->getStats(); osg::Stats* stats = sceneView->getCamera()->getStats();
osg::State* state = sceneView->getState(); osg::State* state = sceneView->getState();
const osg::FrameStamp* fs = state->getFrameStamp(); const osg::FrameStamp* fs = sceneView->getFrameStamp();
unsigned int frameNumber = fs ? fs->getFrameNumber() : 0; unsigned int frameNumber = fs ? fs->getFrameNumber() : 0;
if (!_initialized) if (!_initialized)
@ -839,9 +845,7 @@ void Renderer::cull_draw()
osg::Timer_t beforeDrawTick; osg::Timer_t beforeDrawTick;
bool serializeDraw = sceneView->getDisplaySettings()->getSerializeDrawDispatch(); if (_serializeDraw)
if (serializeDraw)
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_drawSerializerMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_drawSerializerMutex);