osgEarth的Rex引擎原理分析(三十三)分页瓦片卸载器子节点的作用

本文详细分析了osgEarth的Rex引擎中分页瓦片卸载器子节点的作用。在RexTerrainEngineNode的渲染遍历过程中,卸载器通过扫描器判断并添加休眠状态的瓦片节点,随后在更新遍历时移除这些瓦片,同时管理资源释放器,确保在适当时间释放OpenGL资源,维持场景与活跃瓦片寄存器的一致性。
摘要由CSDN通过智能技术生成

目标:(十二)中的问题22

分页瓦片卸载器是在Rex引擎的setMap函数中创建的,创建之初就关联了活跃瓦片寄存器和资源释放器。作用见下面分析。

osgEarthDrivers/engine_rex/RexTerrainEngineNode.cpp
void
RexTerrainEngineNode::setMap(const Map* map, const TerrainOptions& options)
{  
    // Make a tile unloader
    _unloader = new UnloaderGroup( _liveTiles.get() );
    _unloader->setThreshold( _terrainOptions.expirationThreshold().get() );
    _unloader->setReleaser(_releaser.get());
    this->addChild( _unloader.get() );
}

1、渲染遍历时在RexTerrainEngineNode裁剪遍历阶段向卸载器中添加要删除的瓦片节点,如何确定要删除的瓦片节点 由RexTerrainEngineNode的上下文环境中的endCull函数中的扫描器来确定(endCull最终是在RexTerrainEngineNode在渲染遍历时调用):

osgEarthDrivers/engine_rex/EngineContext.cpp
void
EngineContext::endCull(osgUtil::CullVisitor* cv)
{
    std::vector<TileKey> tilesWithChildrenToUnload;
    Scanner scanner(tilesWithChildrenToUnload, cv->getFrameStamp());
    _liveTiles->run( scanner );
    if ( !tilesWithChildrenToUnload.empty() )
    {        
        getUnloader()->unloadChildren( tilesWithChildrenToUnload );
    }
}
osgEarthDrivers/engine_rex/TileNodeRegistry.cpp
void
TileNodeRegistry::run( const TileNodeRegistry::ConstOperation& op ) const
{
    Threading::ScopedReadLock lock( _tilesMutex );
    op.operator()( _tiles );
    OE_TEST << LC << _name << ": tiles=" << _tiles.size() << std::endl;
}

扫描器的扫描过程如下:

osgEarthDrivers/engine_rex/EngineContext.cpp
        enum Policy {
            POLICY_FIND_ALL,
            POLICY_FIND_SOME,
            POLICY_FIND_ONE
        };
        void operator()(const TileNodeRegistry::TileNodeMap& tiles) const
        {
            if ( tiles.empty() ) return;
            unsigned f = _stamp->getFrameNumber(), s = tiles.size();

            switch (_policy)
            {
                case POLICY_FIND_ALL:
                {
                    for (TileNodeRegistry::TileNodeMap::const_iterator i = tiles.begin(); i != tiles.end(); ++i)
                    {
                        const TileNode* tile = i->second.tile.get();
                        if (tile->areSubTilesDormant(_stamp))
                            _keys.push_back(i->first);
                    }
                }
                break;

                case POLICY_FIND_ONE:
                {
                    const TileNode* tile = tiles.at(f%s);
                    if (tile->areSubTilesDormant(_stamp))
                    {
                        _keys.push_back(tile->getKey());
                    }
                }
                break;

                default:
                case POLICY_FIND_SOME:
                {
                    for(unsigned i=0; i<4; ++i) {
                        const TileNode* tile = tiles.at((f+i)%s);
                        if ( tile->areSubTilesDormant(_stamp) )
                            _keys.push_back( tile->getKey() );
                    }
                }
            }
        }

扫描策略默认为POLICY_FIND_ALL,扫描的对象即为活跃瓦片寄存器。对于活跃瓦片寄存器中的每一个瓦片,判断其子瓦片是否处于休眠状态Dormant,也即判断最近一次遍历时的帧号和时间与当前做比

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值