Equalizer
1.4.1
|
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 }