首页 技术 正文
技术 2022年11月14日
0 收藏 683 点赞 4,497 浏览 4066 个字

补充

当然细心的你会发现,_scene->updateSceneGraph(*_updateVisitor)中还有一个imagePager::UpdateSceneGraph()还没有进行讲解,这是因为imagePager和DatabasePager是可以对比这理解的,这里imagePager的主要功能就是加载纹理图片文件。但是imagePager只是负责在另一个线程中加载图片,而没有databasePager的分页功能以及去掉过期数据。这样我们就真的可以重新回到Viewer::updateTraversal()中,继续向下进行了。

Viewer::updateTraversal()

?

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 // if we have a shared state manager prune any unused entries    if (osgDB::Registry::instance()->getSharedStateManager())        osgDB::Registry::instance()->getSharedStateManager()->prune();     // update the Registry object cache.    osgDB::Registry::instance()->updateTimeStampOfObjectsInCacheWithExternalReferences(*getFrameStamp());    osgDB::Registry::instance()->removeExpiredObjectsInCache(*getFrameStamp());      if (_updateOperations.valid())    {        _updateOperations->runOperations(this);    }     if (_incrementalCompileOperation.valid())    {        // merge subgraphs that have been compiled by the incremental compiler operation.        _incrementalCompileOperation->mergeCompiledSubgraphs(getFrameStamp());    }     {        // Do UpdateTraversal for slaves with their own subgraph        for(unsigned int i=0; i<getNumSlaves(); ++i)        {            osg::View::Slave& slave = getSlave(i);            osg::Camera* camera = slave._camera.get();            if(camera && !slave._useMastersSceneData)            {                camera->accept(*_updateVisitor);            }        }    }     {        // call any camera update callbacks, but only traverse that callback, don't traverse its subgraph        // leave that to the scene update traversal.        osg::NodeVisitor::TraversalMode tm = _updateVisitor->getTraversalMode();        _updateVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);         if (_camera.valid() && _camera->getUpdateCallback()) _camera->accept(*_updateVisitor);         for(unsigned int i=0; i<getNumSlaves(); ++i)        {            osg::View::Slave& slave = getSlave(i);            osg::Camera* camera = slave._camera.get();            if (camera && slave._useMastersSceneData && camera->getUpdateCallback())            {                camera->accept(*_updateVisitor);            }        }         _updateVisitor->setTraversalMode(tm);    }     if (_cameraManipulator.valid())    {        setFusionDistance( getCameraManipulator()->getFusionDistanceMode(),                            getCameraManipulator()->getFusionDistanceValue() );         _cameraManipulator->updateCamera(*_camera);    }     updateSlaves();     if (getViewerStats() && getViewerStats()->collectStats("update"))    {        double endUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());         // update current frames stats        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal begin time", beginUpdateTraversal);        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal end time", endUpdateTraversal);        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal time taken", endUpdateTraversal-beginUpdateTraversal);    }
      • 1、大家应该还记得前面提到的SharedStateManager,用于node间储存共享的属性或状态。我们将要遇到的下一个if就是要遍历这个SharedStateManager所有储存的共享状态,删除其中不再被引用到的。
      • 2、更新又一次被外部引用的在缓存中的对象的时间戳,以保证他不会被清除掉。然后就是清除掉已经过期的在缓存中的对象
      • 3、_updateOperations代表更新任务的队列,然后取得任务队列(OperationQueue),注意这里要使用 Mutex 互斥锁,避免用户追加任务时与线程的执行产生冲突。获取任务队列中的一个任务(OperationQueue::getNextOperation)。这个函数看似简单,只要从 std::list 列表中取出一个 osg::Operation 对象就可以了。但是其中还是有诸多的注意事项:首先,如果任务列表是空的,渲染线程将选择暂时阻塞自己(使用 block 函数),直到有新的 Operation 操作加入到队列中为止。其次,我们有一个任务列表迭代器_currentOperationIterator,如果这个迭代器已经到达列表的末尾,则自动将其转至列表首部,这样就可以在线程中循环执行任务列表中的内容。如果迭代器取得了一个 Operation 操作任务,那么我们需要判断这个任务是否将被反复执行,即,迭代器转至任务列表首部之后,是否还可以取得这个任务。判断所用的函数是Operation::getKeep,这个函数返回 true 时,任务将允许反复执行(例如场景筛选和绘制的任务),否则任务将被随即从列表中移除,我们也不会再取得这个 Operation 对象(除非再次将其加入列表)
      • 4、把已经编译好的子图进行合并。然后更新所有从相机自己的子图。调用任何相机更新回调,但只遍历那个回调,不要遍历其子图,将其留给场景更新遍历。
      • 5、使用相机操作器更新相机的位置。然后就是调用所有从相机的更新回调函数。并记录更新循环中的所有的信息。

现在我们总有算是完成了漫长的 updateTraversal 函数之旅。我们明天开始更艰巨的任务osgViewer:: ViewerBase::renderingTraversals()。

原文链接 http://www.3wwang.cn/blog/article.ftl?id=32

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,492
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,495
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,132
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,295