From 685d0b08cbfb6724ebf103b4979ec416273b2f80 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 14 Feb 2002 13:26:37 +0000 Subject: [PATCH] Beginings of reimplementation of stereo support in scene view. Work not complete yet. --- include/osgUtil/SceneView | 12 ++- src/osgUtil/SceneView.cpp | 209 ++++++++++++++++++++------------------ 2 files changed, 121 insertions(+), 100 deletions(-) diff --git a/include/osgUtil/SceneView b/include/osgUtil/SceneView index f70738c39..45a84f429 100644 --- a/include/osgUtil/SceneView +++ b/include/osgUtil/SceneView @@ -214,6 +214,10 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced virtual ~SceneView(); + /** Do cull traversal of attached scene graph using Cull NodeVisitor.*/ + virtual void cullStage(osg::Camera* camera,osgUtil::RenderStage* renderStage); + virtual void drawStage(osgUtil::RenderStage* renderStage); + osg::ref_ptr _sceneData; osg::ref_ptr _globalState; osg::ref_ptr _light; @@ -227,7 +231,13 @@ class OSGUTIL_EXPORT SceneView : public osg::Referenced osg::ref_ptr _cullVisitor; osg::ref_ptr _rendergraph; osg::ref_ptr _renderStage; - + + osg::ref_ptr _cameraLeft; + osg::ref_ptr _cameraRight; + osg::ref_ptr _renderStageLeft; + osg::ref_ptr _renderStageRight; + + osg::ref_ptr _frameStamp; bool _need_compile; diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index 0a5b4e39e..70bd4bd9d 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -143,6 +143,35 @@ void SceneView::app() } void SceneView::cull() +{ + if (_displaySettings.valid() && _displaySettings->getStereo()) + { + + _camera->setScreenDistance(_displaySettings->getScreenDistance()); + + _cameraLeft = new osg::Camera(*_camera); + _cameraRight = new osg::Camera(*_camera); + + float iod = _displaySettings->getEyeSeperation(); + + _cameraLeft->adjustEyeOffsetForStereo(osg::Vec3(-iod*0.5,0.0f,0.0f)); + _cameraRight->adjustEyeOffsetForStereo(osg::Vec3(iod*0.5,0.0f,0.0f)); + + if (!_renderStageLeft.valid()) _renderStageLeft = dynamic_cast(_renderStage->cloneType()); + if (!_renderStageRight.valid()) _renderStageRight = dynamic_cast(_renderStage->cloneType()); + + cullStage(_cameraLeft.get(),_renderStageLeft.get()); + cullStage(_cameraRight.get(),_renderStageRight.get()); + + } + else + { + + cullStage(_camera.get(),_renderStage.get()); + } +} + +void SceneView::cullStage(osg::Camera* camera,osgUtil::RenderStage* renderStage) { if (!_sceneData || !_viewport->valid()) return; @@ -171,39 +200,39 @@ void SceneView::cull() } // get the camera's modelview - osg::Matrix* modelview = new osg::Matrix(_camera->getModelViewMatrix()); + osg::Matrix* modelview = new osg::Matrix(camera->getModelViewMatrix()); // take a copy of camera, and init it home - osg::Camera* camera = new Camera(*_camera); - camera->home(); - camera->attachTransform(osg::Camera::NO_ATTACHED_TRANSFORM); + osg::Camera* local_camera = new Camera(*camera); + local_camera->home(); + local_camera->attachTransform(osg::Camera::NO_ATTACHED_TRANSFORM); _cullVisitor->setLODBias(_lodBias); - _cullVisitor->setCamera(*camera); + _cullVisitor->setCamera(*local_camera); _cullVisitor->setViewport(_viewport.get()); _cullVisitor->setEarthSky(NULL); // reset earth sky on each frame. - // SandB - //now make it compute "clipping directions" needed for detailed culling - if(_cullVisitor->getDetailedCulling()) - _cullVisitor->calcClippingDirections();//only once pre frame + // SandB + //now make it compute "clipping directions" needed for detailed culling + if(_cullVisitor->getDetailedCulling()) + _cullVisitor->calcClippingDirections();//only once pre frame - _renderStage->reset(); + renderStage->reset(); - _renderStage->setViewport(_viewport.get()); - _renderStage->setCamera(camera); - _renderStage->setClearColor(_backgroundColor); + renderStage->setViewport(_viewport.get()); + renderStage->setCamera(local_camera); + renderStage->setClearColor(_backgroundColor); switch(_lightingMode) { case(HEADLIGHT): - _renderStage->addLight(_light.get(),NULL); + renderStage->addLight(_light.get(),NULL); break; case(SKY_LIGHT): - _renderStage->addLight(_light.get(),modelview); + renderStage->addLight(_light.get(),modelview); break; case(NO_SCENEVIEW_LIGHT): break; @@ -228,8 +257,8 @@ void SceneView::cull() { if (earthSky->getRequiresClear()) { - _renderStage->setClearColor(earthSky->getClearColor()); - _renderStage->setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + renderStage->setClearColor(earthSky->getClearColor()); + renderStage->setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // really should set clear mask here, but what to? Need // to consider the stencil and accumulation buffers.. // will defer to later. Robert Osfield. October 2001. @@ -238,7 +267,7 @@ void SceneView::cull() { // we have an earth sky implementation to do the work for use // so we don't need to clear. - _renderStage->setClearMask(0); + renderStage->setClearMask(0); } } @@ -267,10 +296,10 @@ void SceneView::cull() // if required clamp the near plane to prevent negative or near zero // near planes. if(!_cullVisitor->getDetailedCulling()) - { - float min_near_plane = _far_plane*0.0005f; - if (_near_planesetNearFar(_near_plane,_far_plane); camera->setNearFar(_near_plane,_far_plane); - _camera->setNearFar(_near_plane,_far_plane); } } void SceneView::draw() +{ + if (_displaySettings.valid() && _displaySettings->getStereo()) + { + + _camera->setScreenDistance(_displaySettings->getScreenDistance()); + + switch(_displaySettings->getStereoMode()) + { + case(osg::DisplaySettings::QUAD_BUFFER): + { + + glDrawBuffer(GL_BACK_LEFT); + drawStage(_renderStageLeft.get()); + + + glDrawBuffer(GL_BACK_RIGHT); + drawStage(_renderStageRight.get()); + + } + break; + case(osg::DisplaySettings::ANAGLYPHIC): + { + osg::ref_ptr red = new osg::ColorMask; + osg::ref_ptr green = new osg::ColorMask; + + red->setMask(true,false,false,true); + green->setMask(false,true,true,true); + + // draw left eye. + _globalState->setAttribute(red.get()); + _renderStageLeft->setColorMask(red.get()); + drawStage(_renderStageLeft.get()); + + // draw right eye. + _globalState->setAttribute(green.get()); + _renderStageRight->setColorMask(green.get()); + drawStage(_renderStageRight.get()); + + } + break; + default: + { + osg::notify(osg::NOTICE)<<"Warning: stereo camera mode not implemented yet."<< std::endl; + drawStage(_renderStageLeft.get()); + } + break; + } + } + else + { + // bog standard draw. + drawStage(_renderStage.get()); + } + +} + +void SceneView::drawStage(osgUtil::RenderStage* renderStage) { if (!_sceneData || !_viewport->valid()) return; @@ -312,82 +398,7 @@ void SceneView::draw() RenderLeaf* previous = NULL; - - if (_displaySettings.valid() && _displaySettings->getStereo()) - { - - _camera->setScreenDistance(_displaySettings->getScreenDistance()); - - switch(_displaySettings->getStereoMode()) - { - case(osg::DisplaySettings::QUAD_BUFFER): - { - osg::ref_ptr left_camera = new osg::Camera(*_camera); - osg::ref_ptr right_camera = new osg::Camera(*_camera); - - float iod = _displaySettings->getEyeSeperation(); - - left_camera->adjustEyeOffsetForStereo(osg::Vec3(-iod*0.5,0.0f,0.0f)); - right_camera->adjustEyeOffsetForStereo(osg::Vec3(iod*0.5,0.0f,0.0f)); - - 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::DisplaySettings::ANAGLYPHIC): - { - osg::ref_ptr left_camera = new osg::Camera(*_camera); - osg::ref_ptr right_camera = new osg::Camera(*_camera); - - float iod = _displaySettings->getEyeSeperation(); - - left_camera->adjustEyeOffsetForStereo(osg::Vec3(-iod*0.5,0.0f,0.0f)); - right_camera->adjustEyeOffsetForStereo(osg::Vec3(iod*0.5,0.0f,0.0f)); - - osg::ColorMask* red = new osg::ColorMask; - osg::ColorMask* green = new osg::ColorMask; - - red->setMask(true,false,false,true); - green->setMask(false,true,true,true); - - // draw right eye. - _globalState->setAttribute(red); - _renderStage->setColorMask(red); - _renderStage->setCamera(left_camera.get()); - _renderStage->draw(*_state,previous); - - // need to tell the rendering stage that it can be - // called again in this frame. - _renderStage->_stageDrawnThisFrame = false; - - // draw left eye. - _globalState->setAttribute(green); - _renderStage->setColorMask(green); - _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); - } + renderStage->draw(*_state,previous); GLenum errorNo = glGetError(); if (errorNo!=GL_NO_ERROR)