From 34a6b38983dc8d630fde4bbb3d983fce08d5a95e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 15 Apr 2013 14:21:32 +0000 Subject: [PATCH] Preperation for adding stereo support direclty into osgViewer. --- include/osg/DisplaySettings | 23 ++++++ include/osg/Viewport | 12 +++ include/osgUtil/SceneView | 9 ++- include/osgViewer/Renderer | 1 + src/osg/DisplaySettings.cpp | 151 +++++++++++++++++++++++++++++++++--- src/osgUtil/SceneView.cpp | 144 ++++++++++------------------------ src/osgViewer/Renderer.cpp | 30 +++---- 7 files changed, 239 insertions(+), 131 deletions(-) diff --git a/include/osg/DisplaySettings b/include/osg/DisplaySettings index 321440cad..5be2bf844 100644 --- a/include/osg/DisplaySettings +++ b/include/osg/DisplaySettings @@ -15,6 +15,7 @@ #define OSG_DisplaySettings 1 #include +#include #include #include @@ -184,6 +185,11 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced void setSerializeDrawDispatch(bool serializeDrawDispatch) { _serializeDrawDispatch = 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.*/ 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.*/ 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: virtual ~DisplaySettings(); @@ -313,6 +335,7 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced bool _compileContextsHint; bool _serializeDrawDispatch; + bool _useSceneViewForStereoHint; unsigned int _numDatabaseThreadsHint; unsigned int _numHttpDatabaseThreadsHint; diff --git a/include/osg/Viewport b/include/osg/Viewport index 720d037b4..a32d4bef4 100644 --- a/include/osg/Viewport +++ b/include/osg/Viewport @@ -64,6 +64,18 @@ class OSG_EXPORT Viewport : public StateAttribute 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) { _x = x; diff --git a/include/osgUtil/SceneView b/include/osgUtil/SceneView index 21d7b249e..c7767cc44 100644 --- a/include/osgUtil/SceneView +++ b/include/osgUtil/SceneView @@ -406,8 +406,6 @@ class OSGUTIL_EXPORT SceneView : public osg::Object, public osg::CullSettings inline const osg::FrameStamp* getFrameStamp() const { return _frameStamp.get(); } - - inline osg::Matrixd computeLeftEyeProjection(const osg::Matrixd& projection) const { 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); } + /** 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) 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) const; + /** 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); } diff --git a/include/osgViewer/Renderer b/include/osgViewer/Renderer index c2b7c328c..fa4738a17 100644 --- a/include/osgViewer/Renderer +++ b/include/osgViewer/Renderer @@ -86,6 +86,7 @@ class OSGVIEWER_EXPORT Renderer : public osg::GraphicsOperation bool _done; bool _graphicsThreadDoesCull; bool _compileOnNextDraw; + bool _serializeDraw; osg::ref_ptr _sceneView[2]; diff --git a/src/osg/DisplaySettings.cpp b/src/osg/DisplaySettings.cpp index 04ddf97ec..3ff7a7c07 100644 --- a/src/osg/DisplaySettings.cpp +++ b/src/osg/DisplaySettings.cpp @@ -79,6 +79,7 @@ void DisplaySettings::setDisplaySettings(const DisplaySettings& vs) _compileContextsHint = vs._compileContextsHint; _serializeDrawDispatch = vs._serializeDrawDispatch; + _useSceneViewForStereoHint = vs._useSceneViewForStereoHint; _numDatabaseThreadsHint = vs._numDatabaseThreadsHint; _numHttpDatabaseThreadsHint = vs._numHttpDatabaseThreadsHint; @@ -113,6 +114,7 @@ void DisplaySettings::merge(const DisplaySettings& vs) if (vs._compileContextsHint) _compileContextsHint = vs._compileContextsHint; if (vs._serializeDrawDispatch) _serializeDrawDispatch = vs._serializeDrawDispatch; + if (vs._useSceneViewForStereoHint) _useSceneViewForStereoHint = vs._useSceneViewForStereoHint; if (vs._numDatabaseThreadsHint>_numDatabaseThreadsHint) _numDatabaseThreadsHint = vs._numDatabaseThreadsHint; if (vs._numHttpDatabaseThreadsHint>_numHttpDatabaseThreadsHint) _numHttpDatabaseThreadsHint = vs._numHttpDatabaseThreadsHint; @@ -170,6 +172,7 @@ void DisplaySettings::setDefaults() _compileContextsHint = false; _serializeDrawDispatch = true; + _useSceneViewForStereoHint = true; _numDatabaseThreadsHint = 2; _numHttpDatabaseThreadsHint = 1; @@ -251,39 +254,42 @@ static ApplicationUsageProxy DisplaySetting_e14(ApplicationUsage::ENVIRONMENTAL_ "OSG_SERIALIZE_DRAW_DISPATCH ", "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, + "OSG_USE_SCENEVIEW_FOR_STEREO ", + "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 ", "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 ", "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 ", "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 ", "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 ", "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 ", "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", "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", "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 ", "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 ", "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 ", "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 ", "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) { _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); +} diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index 958195ef6..c524e034f 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -429,48 +429,15 @@ void SceneView::updateUniforms() osg::Matrixd SceneView::computeLeftEyeProjectionImplementation(const osg::Matrixd& projection) const { - double iod = _displaySettings->getEyeSeparation(); - 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; - } + return _displaySettings.valid() ? _displaySettings->computeLeftEyeProjectionImplementation(projection) : projection; } 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) { case(USE_FUSION_DISTANCE_VALUE): @@ -480,62 +447,22 @@ osg::Matrixd SceneView::computeLeftEyeViewImplementation(const osg::Matrixd& vie fusionDistance *= _fusionDistanceValue; break; } + double eyeScale = (fusionDistance/sd); - double iod = _displaySettings->getEyeSeparation(); - 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); + return _displaySettings->computeLeftEyeViewImplementation(view, eyeScale); } osg::Matrixd SceneView::computeRightEyeProjectionImplementation(const osg::Matrixd& projection) const { - double iod = _displaySettings->getEyeSeparation(); - 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; - } + return _displaySettings.valid() ? _displaySettings->computeRightEyeProjectionImplementation(projection) : projection; } 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) { case(USE_FUSION_DISTANCE_VALUE): @@ -545,16 +472,9 @@ osg::Matrixd SceneView::computeRightEyeViewImplementation(const osg::Matrixd& vi fusionDistance *= _fusionDistanceValue; break; } + double eyeScale = (fusionDistance/sd); - double iod = _displaySettings->getEyeSeparation(); - 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); + return _displaySettings->computeRightEyeViewImplementation(view, eyeScale); } 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 (!_displaySettings) + { + (*_viewportLeft) = *viewport; + return; + } + switch(_displaySettings->getStereoMode()) { @@ -603,7 +529,7 @@ void SceneView::computeLeftEyeViewport(const osg::Viewport *viewport) break; default: - _viewportLeft->setViewport(viewport->x(),viewport->y(),viewport->width(),viewport->height()); + *(_viewportLeft) = *viewport; break; } } @@ -612,8 +538,14 @@ void SceneView::computeRightEyeViewport(const osg::Viewport *viewport) { if(!viewport) return; - if(!_viewportRight.valid()) _viewportRight = new osg::Viewport; + if(!_viewportRight) _viewportRight = new osg::Viewport; + if (!_displaySettings) + { + (*_viewportRight) = *viewport; + return; + } + switch(_displaySettings->getStereoMode()) { case(osg::DisplaySettings::HORIZONTAL_SPLIT): @@ -653,7 +585,7 @@ void SceneView::computeRightEyeViewport(const osg::Viewport *viewport) break; default: - _viewportRight->setViewport(viewport->x(),viewport->y(),viewport->width(),viewport->height()); + *(_viewportRight) = *viewport; break; } } @@ -740,20 +672,12 @@ void SceneView::cull() _renderInfo.setState(new osg::State); } - osg::State* state = _renderInfo.getState(); if (!_localStateSet) { _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) { 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; 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(); osg::Texture::TextureObjectManager* tom = osg::Texture::getTextureObjectManager(state->getContextID()).get(); diff --git a/src/osgViewer/Renderer.cpp b/src/osgViewer/Renderer.cpp index 2de31babe..0a41d2f20 100644 --- a/src/osgViewer/Renderer.cpp +++ b/src/osgViewer/Renderer.cpp @@ -34,7 +34,6 @@ using namespace osgViewer; //#define DEBUG_MESSAGE OSG_NOTICE #define DEBUG_MESSAGE OSG_DEBUG - OpenGLQuerySupport::OpenGLQuerySupport(): _extensions(0) { @@ -357,6 +356,7 @@ Renderer::Renderer(osg::Camera* camera): _done(false), _graphicsThreadDoesCull(true), _compileOnNextDraw(true), + _serializeDraw(false), _initialized(false), _startTick(0) { @@ -388,6 +388,8 @@ Renderer::Renderer(osg::Camera* camera): osg::DisplaySettings* ds = _camera->getDisplaySettings() ? _camera->getDisplaySettings() : ((view && view->getDisplaySettings()) ? view->getDisplaySettings() : osg::DisplaySettings::instance().get()); + _serializeDraw = ds ? ds->getSerializeDrawDispatch() : false; + unsigned int sceneViewOptions = osgUtil::SceneView::HEADLIGHT; if (view) { @@ -410,9 +412,12 @@ Renderer::Renderer(osg::Camera* camera): _sceneView[0]->setDefaults(sceneViewOptions); _sceneView[1]->setDefaults(sceneViewOptions); - _sceneView[0]->setDisplaySettings(ds); - _sceneView[1]->setDisplaySettings(ds); - + if (ds->getUseSceneViewForStereoHint()) + { + _sceneView[0]->setDisplaySettings(ds); + _sceneView[1]->setDisplaySettings(ds); + } + _sceneView[0]->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() : ((view &&view->getDisplaySettings()) ? view->getDisplaySettings() : osg::DisplaySettings::instance().get()); - sceneView->setDisplaySettings(ds); + if (ds->getUseSceneViewForStereoHint()) + { + sceneView->setDisplaySettings(ds); + } if (view) { @@ -691,7 +699,7 @@ void Renderer::draw() osg::Stats* stats = sceneView->getCamera()->getStats(); osg::State* state = sceneView->getState(); - unsigned int frameNumber = state->getFrameStamp()->getFrameNumber(); + unsigned int frameNumber = sceneView->getFrameStamp()->getFrameNumber(); if (!_initialized) { @@ -723,9 +731,7 @@ void Renderer::draw() osg::Timer_t beforeDrawTick; - bool serializeDraw = sceneView->getDisplaySettings()->getSerializeDrawDispatch(); - - if (serializeDraw) + if (_serializeDraw) { OpenThreads::ScopedLock lock(s_drawSerializerMutex); beforeDrawTick = osg::Timer::instance()->tick(); @@ -794,7 +800,7 @@ void Renderer::cull_draw() osg::Stats* stats = sceneView->getCamera()->getStats(); osg::State* state = sceneView->getState(); - const osg::FrameStamp* fs = state->getFrameStamp(); + const osg::FrameStamp* fs = sceneView->getFrameStamp(); unsigned int frameNumber = fs ? fs->getFrameNumber() : 0; if (!_initialized) @@ -839,9 +845,7 @@ void Renderer::cull_draw() osg::Timer_t beforeDrawTick; - bool serializeDraw = sceneView->getDisplaySettings()->getSerializeDrawDispatch(); - - if (serializeDraw) + if (_serializeDraw) { OpenThreads::ScopedLock lock(s_drawSerializerMutex);