Equalizer  1.4.1
sceneView.cpp
00001 
00002 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
00003  *                           2010-2011 Stefan Eilemann <eile@eyescale.ch>
00004  *
00005  * This library is open source and may be redistributed and/or modified under  
00006  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
00007  * (at your option) any later version.  The full license is in LICENSE file
00008  * included with this distribution, and on the openscenegraph.org website.
00009  * 
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
00013  * OpenSceneGraph Public License for more details.
00014 */
00015 #include "sceneView.h"
00016 
00017 #include <osgUtil/UpdateVisitor>
00018 #include <osgUtil/GLObjectsVisitor>
00019 
00020 #include <osg/Version>
00021 #include <osg/Timer>
00022 #include <osg/GLExtensions>
00023 #include <osg/GLObjects>
00024 #include <osg/Notify>
00025 #include <osg/Texture>
00026 #include <osg/AlphaFunc>
00027 #include <osg/TexEnv>
00028 #include <osg/ColorMatrix>
00029 #include <osg/LightModel>
00030 #include <osg/CollectOccludersVisitor>
00031 
00032 #include <osg/GLU>
00033 
00034 #include <iterator>
00035 
00036 using namespace osg;
00037 using namespace osgUtil;
00038 
00039 namespace osgScaleViewer
00040 {
00041 
00042 SceneView::SceneView( osg::DisplaySettings* ds)
00043 {
00044     _displaySettings = ds;
00045 
00046     _lightingMode=NO_SCENEVIEW_LIGHT;
00047     
00048     _prioritizeTextures = false;
00049     
00050     setCamera(new Camera);
00051     _camera->setViewport(new Viewport);
00052     _camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f));
00053     
00054     _initCalled = false;
00055 
00056     _camera->setDrawBuffer(GL_BACK);
00057 
00058     _requiresFlush = true;
00059     
00060     _activeUniforms = DEFAULT_UNIFORMS;
00061     
00062     _previousFrameTime = 0;
00063     _previousSimulationTime = 0;
00064     
00065     _dynamicObjectCount = 0;
00066 }
00067 
00068 SceneView::SceneView(const SceneView& rhs, const osg::CopyOp& copyop):
00069     osg::Object(rhs,copyop),
00070     osg::CullSettings(rhs)
00071 {
00072     _displaySettings = rhs._displaySettings;
00073 
00074     _lightingMode = rhs._lightingMode;
00075     
00076     _prioritizeTextures = rhs._prioritizeTextures;
00077     
00078     _camera = rhs._camera;
00079     _cameraWithOwnership = rhs._cameraWithOwnership;
00080     
00081     _initCalled = false;
00082 
00083     _requiresFlush = rhs._requiresFlush;
00084     
00085     _activeUniforms = rhs._activeUniforms;
00086     
00087     _previousFrameTime = 0;
00088     _previousSimulationTime = 0;
00089     
00090     _dynamicObjectCount = 0;
00091 }
00092 
00093 SceneView::~SceneView()
00094 {
00095 }
00096 
00097 
00098 void SceneView::setDefaults(unsigned int options)
00099 {
00100     osg::CullSettings::setDefaults();
00101 
00102     _camera->getProjectionMatrix().makePerspective(50.0f,1.4f,1.0f,10000.0f);
00103     _camera->getViewMatrix().makeIdentity();
00104 
00105     if (!_globalStateSet) _globalStateSet = new osg::StateSet;
00106     else _globalStateSet->clear();
00107 
00108     if ((options & HEADLIGHT) || (options & SKY_LIGHT))
00109     {
00110         #if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE)
00111             _lightingMode=(options&HEADLIGHT) ? HEADLIGHT : SKY_LIGHT;
00112             _light = new osg::Light;
00113             _light->setLightNum(0);
00114             _light->setAmbient(Vec4(0.00f,0.0f,0.00f,1.0f));
00115             _light->setDiffuse(Vec4(0.8f,0.8f,0.8f,1.0f));
00116             _light->setSpecular(Vec4(1.0f,1.0f,1.0f,1.0f));
00117 
00118 
00119             _globalStateSet->setAssociatedModes(_light.get(),osg::StateAttribute::ON);
00120 
00121             // enable lighting by default.
00122             _globalStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
00123         #endif
00124         
00125         #if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) && defined(OSG_GL_FIXED_FUNCTION_AVAILABLE)
00126             osg::LightModel* lightmodel = new osg::LightModel;
00127             lightmodel->setAmbientIntensity(osg::Vec4(0.1f,0.1f,0.1f,1.0f));
00128             _globalStateSet->setAttributeAndModes(lightmodel, osg::StateAttribute::ON);
00129         #endif
00130     }
00131     else
00132     {
00133         _lightingMode = NO_SCENEVIEW_LIGHT;
00134     }
00135  
00136     _renderInfo.setState(new State);
00137     
00138     _stateGraph = new StateGraph;
00139     _renderStage = new RenderStage;
00140 
00141 
00142     if (options & COMPILE_GLOBJECTS_AT_INIT)
00143     {
00144         GLObjectsVisitor::Mode  dlvMode = GLObjectsVisitor::COMPILE_DISPLAY_LISTS |
00145                                           GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES | 
00146                                           GLObjectsVisitor::CHECK_BLACK_LISTED_MODES;
00147 
00148     #ifdef __sgi
00149         dlvMode = GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES;
00150     #endif
00151 
00152         // sgi's IR graphics has a problem with lighting and display lists, as it seems to store 
00153         // lighting state with the display list, and the display list visitor doesn't currently apply
00154         // state before creating display lists. So will disable the init visitor default, this won't
00155         // affect functionality since the display lists will be created as and when needed.
00156         GLObjectsVisitor* dlv = new GLObjectsVisitor(dlvMode);
00157         dlv->setNodeMaskOverride(0xffffffff);
00158         _initVisitor = dlv;
00159 
00160     }
00161     
00162     _updateVisitor = new UpdateVisitor;
00163 
00164     _cullVisitor = CullVisitor::create();
00165 
00166     _cullVisitor->setStateGraph(_stateGraph.get());
00167     _cullVisitor->setRenderStage(_renderStage.get());
00168 
00169     _globalStateSet->setGlobalDefaults();
00170 
00171     #if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE)
00172         // set up an texture environment by default to speed up blending operations.
00173          osg::TexEnv* texenv = new osg::TexEnv;
00174          texenv->setMode(osg::TexEnv::MODULATE);
00175          _globalStateSet->setTextureAttributeAndModes(0,texenv, osg::StateAttribute::ON);
00176     #endif
00177          
00178     _camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f));
00179 }
00180 
00181 void SceneView::setCamera(osg::Camera* camera, bool assumeOwnershipOfCamera)
00182 {
00183     if (camera)
00184     {
00185         _camera = camera;
00186     }
00187     else
00188     {
00189         osg::notify(osg::NOTICE)<<"Warning: attempt to assign a NULL camera to SceneView not permitted."<<std::endl;
00190     }
00191     
00192     if (assumeOwnershipOfCamera)
00193     {
00194         _cameraWithOwnership = _camera.get();
00195     }
00196     else
00197     {
00198         _cameraWithOwnership = 0;
00199     }
00200 }
00201 
00202 void SceneView::setSceneData(osg::Node* node)
00203 {
00204     // take a temporary reference to node to prevent the possibility
00205     // of it getting deleted when when we do the camera clear of children. 
00206     osg::ref_ptr<osg::Node> temporaryRefernce = node;
00207     
00208     // remove pre existing children
00209     _camera->removeChildren(0, _camera->getNumChildren());
00210     
00211     // add the new one in.
00212     _camera->addChild(node);
00213 }
00214 
00215 void SceneView::init()
00216 {
00217     _initCalled = true;
00218 
00219     // force the initialization of the OpenGL extension string
00220     // to try and work around a Windows NVidia driver bug circa Oct 2006.
00221     osg::isGLExtensionSupported(_renderInfo.getState()->getContextID(),"");
00222 
00223     if (_camera.valid() && _initVisitor.valid())
00224     {
00225         _initVisitor->reset();
00226         _initVisitor->setFrameStamp(_frameStamp.get());
00227         
00228         GLObjectsVisitor* dlv = dynamic_cast<GLObjectsVisitor*>(_initVisitor.get());
00229         if (dlv) dlv->setState(_renderInfo.getState());
00230         
00231         if (_frameStamp.valid())
00232         {
00233              _initVisitor->setTraversalNumber(_frameStamp->getFrameNumber());
00234         }
00235         
00236         _camera->accept(*_initVisitor.get());
00237         
00238     } 
00239 }
00240 
00241 void SceneView::updateUniforms()
00242 {
00243     if (!_localStateSet)
00244     {
00245         _localStateSet = new osg::StateSet;
00246     }
00247 
00248     if (!_localStateSet) return;
00249     
00250     if ((_activeUniforms & FRAME_NUMBER_UNIFORM) && _frameStamp.valid())
00251     {
00252 #if OSG_MIN_VERSION_REQUIRED(2,9,11)
00253         osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_FrameNumber",osg::Uniform::UNSIGNED_INT);
00254 #else
00255         osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_FrameNumber",osg::Uniform::INT);
00256 #endif
00257 
00258         uniform->set(_frameStamp->getFrameNumber());        
00259     }
00260     
00261     if ((_activeUniforms & FRAME_TIME_UNIFORM) && _frameStamp.valid())
00262     {
00263         osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_FrameTime",osg::Uniform::FLOAT);
00264         uniform->set(static_cast<float>(_frameStamp->getReferenceTime()));
00265     }
00266     
00267     if ((_activeUniforms & DELTA_FRAME_TIME_UNIFORM) && _frameStamp.valid())
00268     {
00269         float delta_frame_time = (_previousFrameTime != 0.0) ? static_cast<float>(_frameStamp->getReferenceTime()-_previousFrameTime) : 0.0f;
00270         _previousFrameTime = _frameStamp->getReferenceTime();
00271         
00272         osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_DeltaFrameTime",osg::Uniform::FLOAT);
00273         uniform->set(delta_frame_time);
00274     }
00275     
00276     if ((_activeUniforms & SIMULATION_TIME_UNIFORM) && _frameStamp.valid())
00277     {
00278         osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_SimulationTime",osg::Uniform::FLOAT);
00279         uniform->set(static_cast<float>(_frameStamp->getSimulationTime()));
00280     }
00281     
00282     if ((_activeUniforms & DELTA_SIMULATION_TIME_UNIFORM) && _frameStamp.valid())
00283     {
00284         float delta_simulation_time = (_previousSimulationTime != 0.0) ? static_cast<float>(_frameStamp->getSimulationTime()-_previousSimulationTime) : 0.0f;
00285         _previousSimulationTime = _frameStamp->getSimulationTime();
00286         
00287         osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_DeltaSimulationTime",osg::Uniform::FLOAT);
00288         uniform->set(delta_simulation_time);
00289     }
00290     
00291     if (_activeUniforms & VIEW_MATRIX_UNIFORM)
00292     {
00293         osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_ViewMatrix",osg::Uniform::FLOAT_MAT4);
00294         uniform->set(getViewMatrix());
00295     }
00296 
00297     if (_activeUniforms & VIEW_MATRIX_INVERSE_UNIFORM)
00298     {
00299         osg::Uniform* uniform = _localStateSet->getOrCreateUniform("osg_ViewMatrixInverse",osg::Uniform::FLOAT_MAT4);
00300         uniform->set(osg::Matrix::inverse(getViewMatrix()));
00301     }
00302 
00303 }
00304 
00305 void SceneView::setLightingMode(LightingMode mode)
00306 {
00307     if (mode==_lightingMode) return;
00308     
00309     if (_lightingMode!=NO_SCENEVIEW_LIGHT)
00310     {
00311         // remove GL_LIGHTING mode
00312         _globalStateSet->removeMode(GL_LIGHTING);
00313 
00314         if (_light.valid())
00315         {
00316             _globalStateSet->removeAssociatedModes(_light.get());
00317         }
00318 
00319     }
00320 
00321     _lightingMode = mode;
00322 
00323     if (_lightingMode!=NO_SCENEVIEW_LIGHT)
00324     {
00325         #if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE)
00326             // add GL_LIGHTING mode
00327             _globalStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
00328             if (_light.valid()) 
00329             {
00330                 _globalStateSet->setAssociatedModes(_light.get(), osg::StateAttribute::ON);
00331             }
00332         #endif
00333     }
00334 }
00335 
00336 void SceneView::inheritCullSettings(const osg::CullSettings& settings, unsigned int inheritanceMask)
00337 {
00338     if (_camera.valid() && _camera->getView()) 
00339     {
00340         if (inheritanceMask & osg::CullSettings::LIGHTING_MODE)
00341         {
00342             LightingMode newLightingMode = _lightingMode;
00343         
00344             switch(_camera->getView()->getLightingMode())
00345             {
00346                 case(osg::View::NO_LIGHT): newLightingMode = NO_SCENEVIEW_LIGHT; break;
00347                 case(osg::View::HEADLIGHT): newLightingMode = HEADLIGHT; break;
00348                 case(osg::View::SKY_LIGHT): newLightingMode = SKY_LIGHT; break;
00349             }
00350             
00351             if (newLightingMode != _lightingMode)
00352             {
00353                 setLightingMode(newLightingMode);
00354             }
00355         }
00356                 
00357         if (inheritanceMask & osg::CullSettings::LIGHT)
00358         {
00359             setLight(_camera->getView()->getLight());
00360         }
00361     }
00362     
00363     osg::CullSettings::inheritCullSettings(settings, inheritanceMask);
00364 }
00365 
00366 
00367 void SceneView::cull()
00368 {
00369     _dynamicObjectCount = 0;
00370 
00371     if (_camera->getNodeMask()==0) return;
00372 
00373     _renderInfo.setView(_camera->getView());
00374 
00375     // update the active uniforms
00376     updateUniforms();
00377 
00378     if (!_renderInfo.getState())
00379     {
00380         osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView::_state attached, creating a default state automatically."<< std::endl;
00381 
00382         // note the constructor for osg::State will set ContextID to 0 which will be fine to single context graphics
00383         // applications which is ok for most apps, but not multiple context/pipe applications.
00384         _renderInfo.setState(new osg::State);
00385     }
00386     
00387     osg::State* state = _renderInfo.getState();
00388 
00389     if (!_localStateSet)
00390     {
00391         _localStateSet = new osg::StateSet;
00392     }
00393     
00394     // we in theory should be able to be able to bypass reset, but we'll call it just incase.
00395     //_state->reset();
00396    
00397     state->setFrameStamp(_frameStamp.get());
00398     state->setDisplaySettings(_displaySettings.get());
00399 
00400 
00401     if (!_cullVisitor)
00402     {
00403         osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView:: attached, creating a default CullVisitor automatically."<< std::endl;
00404         _cullVisitor = CullVisitor::create();
00405     }
00406     if (!_stateGraph)
00407     {
00408         osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView:: attached, creating a global default StateGraph automatically."<< std::endl;
00409         _stateGraph = new StateGraph;
00410     }
00411     if (!_renderStage)
00412     {
00413         osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView::_renderStage attached, creating a default RenderStage automatically."<< std::endl;
00414         _renderStage = new RenderStage;
00415     }
00416 
00417     _cullVisitor->setTraversalMask(_cullMask);
00418     bool computeNearFar = cullStage(getProjectionMatrix(),getViewMatrix(),_cullVisitor.get(),_stateGraph.get(),_renderStage.get(),getViewport());
00419 
00420     if (computeNearFar)
00421     {
00422         CullVisitor::value_type zNear = _cullVisitor->getCalculatedNearPlane();
00423         CullVisitor::value_type zFar = _cullVisitor->getCalculatedFarPlane();
00424         _cullVisitor->clampProjectionMatrix(getProjectionMatrix(),zNear,zFar);
00425     }
00426 }
00427 
00428 bool SceneView::cullStage(const osg::Matrixd& projection,const osg::Matrixd& modelview,osgUtil::CullVisitor* cullVisitor, osgUtil::StateGraph* rendergraph, osgUtil::RenderStage* renderStage, osg::Viewport *viewport)
00429 {
00430 
00431     if (!_camera || !viewport) return false;
00432 
00433     osg::ref_ptr<RefMatrix> proj = new osg::RefMatrix(projection);
00434     osg::ref_ptr<RefMatrix> mv = new osg::RefMatrix(modelview);
00435 
00436     // collect any occluder in the view frustum.
00437     if (_camera->containsOccluderNodes())
00438     {
00439         //std::cout << "Scene graph contains occluder nodes, searching for them"<<std::endl;
00440         
00441         
00442         if (!_collectOccludersVisitor) _collectOccludersVisitor = new osg::CollectOccludersVisitor;
00443         
00444         _collectOccludersVisitor->inheritCullSettings(*this);
00445         
00446         _collectOccludersVisitor->reset();
00447         
00448         _collectOccludersVisitor->setFrameStamp(_frameStamp.get());
00449 
00450         // use the frame number for the traversal number.
00451         if (_frameStamp.valid())
00452         {
00453              _collectOccludersVisitor->setTraversalNumber(_frameStamp->getFrameNumber());
00454         }
00455 
00456         _collectOccludersVisitor->pushViewport(viewport);
00457         _collectOccludersVisitor->pushProjectionMatrix(proj.get());
00458         _collectOccludersVisitor->pushModelViewMatrix(mv.get(),osg::Transform::ABSOLUTE_RF);
00459 
00460         // traverse the scene graph to search for occluder in there new positions.
00461         _collectOccludersVisitor->traverse(*_camera);
00462 
00463         _collectOccludersVisitor->popModelViewMatrix();
00464         _collectOccludersVisitor->popProjectionMatrix();
00465         _collectOccludersVisitor->popViewport();
00466         
00467         // sort the occluder from largest occluder volume to smallest.
00468         _collectOccludersVisitor->removeOccludedOccluders();
00469         
00470         
00471         osg::notify(osg::DEBUG_INFO) << "finished searching for occluder - found "<<_collectOccludersVisitor->getCollectedOccluderSet().size()<<std::endl;
00472            
00473         cullVisitor->getOccluderList().clear();
00474         std::copy(_collectOccludersVisitor->getCollectedOccluderSet().begin(),_collectOccludersVisitor->getCollectedOccluderSet().end(), std::back_insert_iterator<CullStack::OccluderList>(cullVisitor->getOccluderList()));
00475     }
00476     
00477 
00478 
00479     cullVisitor->reset();
00480 
00481     cullVisitor->setFrameStamp(_frameStamp.get());
00482 
00483     // use the frame number for the traversal number.
00484     if (_frameStamp.valid())
00485     {
00486          cullVisitor->setTraversalNumber(_frameStamp->getFrameNumber());
00487     }
00488 
00489     cullVisitor->inheritCullSettings(*this);
00490 
00491     cullVisitor->setStateGraph(rendergraph);
00492     cullVisitor->setRenderStage(renderStage);
00493 
00494     cullVisitor->setRenderInfo( _renderInfo );
00495 
00496     renderStage->reset();
00497 
00498     // comment out reset of rendergraph since clean is more efficient.
00499     //  rendergraph->reset();
00500 
00501     // use clean of the rendergraph rather than reset, as it is able to
00502     // reuse the structure on the rendergraph in the next frame. This
00503     // achieves a certain amount of frame cohereancy of memory allocation.
00504     rendergraph->clean();
00505 
00506     renderStage->setViewport(viewport);
00507     renderStage->setClearColor(_camera->getClearColor());
00508     renderStage->setClearDepth(_camera->getClearDepth());
00509     renderStage->setClearAccum(_camera->getClearAccum());
00510     renderStage->setClearStencil(_camera->getClearStencil());
00511     renderStage->setClearMask(_camera->getClearMask());
00512     
00513 #if 1    
00514     renderStage->setCamera(_camera.get());
00515 #endif
00516 
00517     #if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE)
00518         switch(_lightingMode)
00519         {
00520         case(HEADLIGHT):
00521             if (_light.valid()) renderStage->addPositionedAttribute(NULL,_light.get());
00522             else osg::notify(osg::WARN)<<"Warning: no osg::Light attached to ogUtil::SceneView to provide head light.*/"<<std::endl;
00523             break;
00524         case(SKY_LIGHT):
00525             if (_light.valid()) renderStage->addPositionedAttribute(mv.get(),_light.get());
00526             else osg::notify(osg::WARN)<<"Warning: no osg::Light attached to ogUtil::SceneView to provide sky light.*/"<<std::endl;
00527             break;
00528         default:
00529             break;
00530         }            
00531     #endif
00532     
00533     if (_globalStateSet.valid()) cullVisitor->pushStateSet(_globalStateSet.get());
00534     if (_secondaryStateSet.valid()) cullVisitor->pushStateSet(_secondaryStateSet.get());
00535     if (_localStateSet.valid()) cullVisitor->pushStateSet(_localStateSet.get());
00536 
00537 
00538     cullVisitor->pushViewport(viewport);
00539     cullVisitor->pushProjectionMatrix(proj.get());
00540     cullVisitor->pushModelViewMatrix(mv.get(),osg::Transform::ABSOLUTE_RF);
00541 
00542     // traverse the scene graph to generate the rendergraph.    
00543     // If the camera has a cullCallback execute the callback which has the  
00544     // requirement that it must traverse the camera's children.
00545     {
00546        osg::NodeCallback* callback = _camera->getCullCallback();
00547        if (callback) (*callback)(_camera.get(), cullVisitor);
00548        else cullVisitor->traverse(*_camera);
00549     }
00550 
00551 
00552     cullVisitor->popModelViewMatrix();
00553     cullVisitor->popProjectionMatrix();
00554     cullVisitor->popViewport();
00555 
00556     if (_localStateSet.valid()) cullVisitor->popStateSet();
00557     if (_secondaryStateSet.valid()) cullVisitor->popStateSet();
00558     if (_globalStateSet.valid()) cullVisitor->popStateSet();
00559     
00560 
00561     renderStage->sort();
00562 
00563     // prune out any empty StateGraph children.
00564     // note, this would be not required if the rendergraph had been
00565     // reset at the start of each frame (see top of this method) but
00566     // a clean has been used instead to try to minimize the amount of
00567     // allocation and deleteing of the StateGraph nodes.
00568     rendergraph->prune();
00569     
00570     // set the number of dynamic objects in the scene.    
00571     _dynamicObjectCount += renderStage->computeNumberOfDynamicRenderLeaves();
00572 
00573 
00574     bool computeNearFar = (cullVisitor->getComputeNearFarMode()!=osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR) && getSceneData()!=0;
00575     return computeNearFar;
00576 }
00577 
00578 void SceneView::releaseAllGLObjects()
00579 {
00580     if (!_camera) return;
00581    
00582     _camera->releaseGLObjects(_renderInfo.getState());
00583     
00584     // we need to reset State as it keeps handles to Program objects.
00585     if (_renderInfo.getState()) _renderInfo.getState()->reset();
00586 }
00587 
00588 
00589 void SceneView::flushAllDeletedGLObjects()
00590 {
00591     _requiresFlush = false;
00592     
00593     osg::flushAllDeletedGLObjects(getState()->getContextID());
00594  }
00595 
00596 void SceneView::flushDeletedGLObjects(double& availableTime)
00597 {
00598     osg::State* state = _renderInfo.getState();
00599 
00600     _requiresFlush = false;
00601 
00602     double currentTime = state->getFrameStamp()?state->getFrameStamp()->getReferenceTime():0.0;
00603 
00604     osg::flushDeletedGLObjects(getState()->getContextID(), currentTime, availableTime);
00605 }
00606 
00607 void SceneView::draw()
00608 {
00609     if (_camera->getNodeMask()==0) return;
00610 
00611     osg::State* state = _renderInfo.getState();
00612     state->initializeExtensionProcs();
00613 
00614     osg::Texture::TextureObjectManager* tom = osg::Texture::getTextureObjectManager(state->getContextID()).get();
00615     tom->newFrame(state->getFrameStamp());
00616 
00617     osg::GLBufferObjectManager* bom = osg::GLBufferObjectManager::getGLBufferObjectManager(state->getContextID()).get();
00618     bom->newFrame(state->getFrameStamp());
00619 
00620     if (!_initCalled) init();
00621 
00622     // note, to support multi-pipe systems the deletion of OpenGL display list
00623     // and texture objects is deferred until the OpenGL context is the correct
00624     // context for when the object were originally created.  Here we know what
00625     // context we are in so can flush the appropriate caches.
00626     
00627     if (_requiresFlush)
00628     {
00629         double availableTime = 0.005;
00630         flushDeletedGLObjects(availableTime);
00631     }
00632 
00633     // assume the the draw which is about to happen could generate GL objects that need flushing in the next frame.
00634     _requiresFlush = true;
00635 
00636     state->setInitialViewMatrix(new osg::RefMatrix(getViewMatrix()));
00637 
00638     RenderLeaf* previous = NULL;
00639 
00640     _localStateSet->setAttribute(getViewport());
00641 
00642     // bog standard draw.
00643     _renderStage->drawPreRenderStages(_renderInfo,previous);
00644     _renderStage->draw(_renderInfo,previous);
00645     
00646     // re apply the defalt OGL state.
00647     state->popAllStateSets();
00648     state->apply();
00649 
00650 #if 0
00651     if (_camera->getPostDrawCallback())
00652     {
00653         (*(_camera->getPostDrawCallback()))(*_camera);
00654     }
00655 #endif
00656 
00657     if (state->getCheckForGLErrors()!=osg::State::NEVER_CHECK_GL_ERRORS)
00658     {
00659         if (state->checkGLErrors("end of SceneView::draw()"))
00660         {
00661             // go into debug mode of OGL error in a fine grained way to help
00662             // track down OpenGL errors.
00663             state->setCheckForGLErrors(osg::State::ONCE_PER_ATTRIBUTE);
00664         }
00665     }
00666 
00667 // #define REPORT_TEXTURE_MANAGER_STATS
00668 #ifdef REPORT_TEXTURE_MANAGER_STATS
00669     tom->reportStats();
00670     bom->reportStats();
00671 #endif
00672 
00673     // osg::notify(osg::NOTICE)<<"SceneView  draw() DynamicObjectCount"<<getState()->getDynamicObjectCount()<<std::endl;
00674 
00675 }
00676 
00681 bool SceneView::projectWindowIntoObject(const osg::Vec3& window,osg::Vec3& object) const
00682 {
00683     osg::Matrix inverseMVPW;
00684     inverseMVPW.invert(computeMVPW());
00685     
00686     object = window*inverseMVPW;
00687     
00688     return true;
00689 }
00690 
00691 
00697 bool SceneView::projectWindowXYIntoObject(int x,int y,osg::Vec3& near_point,osg::Vec3& far_point) const
00698 {
00699     osg::Matrix inverseMVPW;
00700     inverseMVPW.invert(computeMVPW());
00701     
00702     near_point = osg::Vec3(x,y,0.0f)*inverseMVPW;
00703     far_point = osg::Vec3(x,y,1.0f)*inverseMVPW;
00704         
00705     return true;
00706 }
00707 
00708 
00713 bool SceneView::projectObjectIntoWindow(const osg::Vec3& object,osg::Vec3& window) const
00714 {
00715     window = object*computeMVPW();
00716     return true;
00717 }
00718 
00719 const osg::Matrix SceneView::computeMVPW() const
00720 {
00721     osg::Matrix matrix( getViewMatrix() * getProjectionMatrix());
00722         
00723     if (getViewport())
00724         matrix.postMult(getViewport()->computeWindowMatrix());
00725     else
00726         osg::notify(osg::WARN)<<"osg::Matrix SceneView::computeMVPW() - error no viewport attached to SceneView, coords will be computed inccorectly."<<std::endl;
00727 
00728     return matrix;
00729 }
00730 
00731 void SceneView::clearArea(int x,int y,int width,int height,const osg::Vec4& color)
00732 {
00733     osg::ref_ptr<osg::Viewport> viewport = new osg::Viewport;
00734     viewport->setViewport(x,y,width,height);
00735 
00736     _renderInfo.getState()->applyAttribute(viewport.get());
00737     
00738     glScissor( x, y, width, height );
00739     glEnable( GL_SCISSOR_TEST );
00740     glClearColor( color[0], color[1], color[2], color[3]);
00741     glClear( GL_COLOR_BUFFER_BIT);
00742     glDisable( GL_SCISSOR_TEST );
00743 }
00744 
00745 void SceneView::setProjectionMatrixAsOrtho(double left, double right,
00746                                            double bottom, double top,
00747                                            double zNear, double zFar)
00748 {
00749     setProjectionMatrix(osg::Matrixd::ortho(left, right,
00750                                            bottom, top,
00751                                            zNear, zFar));
00752 }                                           
00753 
00754 void SceneView::setProjectionMatrixAsOrtho2D(double left, double right,
00755                                              double bottom, double top)
00756 {
00757     setProjectionMatrix(osg::Matrixd::ortho2D(left, right,
00758                                              bottom, top));
00759 }
00760 
00761 void SceneView::setProjectionMatrixAsFrustum(double left, double right,
00762                                              double bottom, double top,
00763                                              double zNear, double zFar)
00764 {
00765     setProjectionMatrix(osg::Matrixd::frustum(left, right,
00766                                              bottom, top,
00767                                              zNear, zFar));
00768 }
00769 
00770 void SceneView::setProjectionMatrixAsPerspective(double fovy,double aspectRatio,
00771                                                  double zNear, double zFar)
00772 {
00773     setProjectionMatrix(osg::Matrixd::perspective(fovy,aspectRatio,
00774                                                  zNear, zFar));
00775 }                                      
00776 
00777 bool SceneView::getProjectionMatrixAsOrtho(double& left, double& right,
00778                                            double& bottom, double& top,
00779                                            double& zNear, double& zFar) const
00780 {
00781     return getProjectionMatrix().getOrtho(left, right,
00782                                        bottom, top,
00783                                        zNear, zFar);
00784 }
00785 
00786 bool SceneView::getProjectionMatrixAsFrustum(double& left, double& right,
00787                                              double& bottom, double& top,
00788                                              double& zNear, double& zFar) const
00789 {
00790     return getProjectionMatrix().getFrustum(left, right,
00791                                          bottom, top,
00792                                          zNear, zFar);
00793 }                                  
00794 
00795 bool SceneView::getProjectionMatrixAsPerspective(double& fovy,double& aspectRatio,
00796                                                  double& zNear, double& zFar) const
00797 {
00798     return getProjectionMatrix().getPerspective(fovy, aspectRatio, zNear, zFar);
00799 }                                                 
00800 
00801 void SceneView::setViewMatrixAsLookAt(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up)
00802 {
00803     setViewMatrix(osg::Matrixd::lookAt(eye,center,up));
00804 }
00805 
00806 void SceneView::getViewMatrixAsLookAt(osg::Vec3& eye,osg::Vec3& center,osg::Vec3& up,float lookDistance) const
00807 {
00808     getViewMatrix().getLookAt(eye,center,up,lookDistance);
00809 }
00810 
00811 bool SceneView::getStats(osgUtil::Statistics& stats)
00812 {
00813     return _renderStage->getStats(stats);
00814 }
00815 
00816 void SceneView::collateReferencesToDependentCameras()
00817 {
00818     if (_renderStage.valid()) _renderStage->collateReferencesToDependentCameras();
00819 }
00820 
00821 void SceneView::clearReferencesToDependentCameras()
00822 {
00823     if (_renderStage.valid()) _renderStage->clearReferencesToDependentCameras();
00824 }
00825 }
Generated on Mon Nov 26 2012 14:41:49 for Equalizer 1.4.1 by  doxygen 1.7.6.1