osgEarth的Rex引擎原理分析(三十四)资源释放器子节点的作用

本文深入探讨osgEarth的Rex引擎中资源释放器子节点的角色,它在setMap方法中创建,用于在osgUtil::SceneView::draw时释放过期的OpenGL资源。资源释放器通过引用计数管理瓦片节点,确保在正确时机释放内存,同时解释了osg::State在释放OpenGL资源中的作用。

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

资源释放器器子节点在rex引擎的setMap中创建,用于释放过期对象的opengl资源

osgEarthDrivers/engine_rex/RexTerrainEngineNode.cpp
void
RexTerrainEngineNode::setMap(const Map* map, const TerrainOptions& options)
{
    // A resource releaser that will call releaseGLObjects() on expired objects.
    _releaser = new ResourceReleaser();
    this->addChild(_releaser.get());
}

由(三十三)可知

对要移除的瓦片节点,放入资源释放器(本质是osg::Drawable对象),释放分配的opengl资源。并不是立即释放,而是要等到osgUtil::SceneView::draw时最终调用资源释放器的drawImplementation时进行释放,该draw不一定在帧循环中调用。资源释放器通过引用指针的方式管理要释放的瓦片节点,因此(3)中的移除不会真正从内存中移除,只有资源释放器移除后才会真正从内存中移除。

 osgEarth/ResourceReleaser.cpp
    void
    ResourceReleaser::releaseGLObjects(osg::State* state) const
    {
        osg::Drawable::releaseGLObjects(state);
     
        if (!_toRelease.empty())
        {
            Threading::ScopedMutexLock lock(_mutex);
            if (!_toRelease.empty())
            {
                METRIC_SCOPED("ResourceReleaser");
                for (ObjectList::const_iterator i = _toRelease.begin(); i != _toRelease.end(); ++i)
                {
                    osg::Object* object = i->get();
                    object->releaseGLObjects(state);
                }
                OE_DEBUG << LC << "Released " << _toRelease.size() &l
<think>好的,我现在需要解决用户提到的在osgEarth中添加DrapableNode后导致图片纹理丢失的问题。首先,我得理解DrapableNode的作用以及它可能如何影响纹理。根据用户提供的引用,特别是引用[2]中关于osgEarth绘制几何体的部分,知道设置顶点数组和PrimitiveSet是关键步骤。可能DrapableNode在添加到场景时,覆盖或修改了原有的状态集(StateSet),导致纹理没有被正确应用。 用户的问题可能与状态集的继承或覆盖有关。在引用[1]中提到,ImageLayer会设置VirtualProgram到其StateSet中。如果DrapableNode的节点也有自己的StateSet,可能会与父节点的StateSet冲突,导致纹理未被正确渲染。需要检查DrapableNode或其父节点的状态设置,确保纹理相关的属性和Uniform没有被覆盖或禁用。 另外,引用[3]中的场景树结构和数据加载流程可能涉及节点加载时的状态管理。如果在加载过程中某些状态被重置,可能导致纹理丢失。可能需要确保在添加DrapableNode后,相关的纹理和着色器状态被正确保留或重新应用。 可能的解决方案包括:检查纹理坐标是否正确设置,确认纹理单元是否冲突,调整渲染顺序以确保纹理在后期正确应用,或者手动重新绑定纹理相关的状态。需要验证这些步骤,特别是检查DrapableNode的StateSet是否覆盖了原有设置,并确保纹理参数正确配置。</think>关于osgEarth中DrapableNode添加后导致图片纹理丢失的问题,以下是分步解决方案: ### 1. 检查纹理坐标设置 DrapableNode可能覆盖了原始几何体的纹理坐标属性,需手动重新绑定: ```cpp // 创建纹理坐标数组 osg::ref_ptr<osg::Vec2Array> texcoords = new osg::Vec2Array; // 填充纹理坐标数据... geometry->setTexCoordArray(0, texcoords); // 必须明确指定纹理单元0 ``` ### 2. 验证纹理状态继承 DrapableNode会创建新的StateSet,需确保纹理状态正确继承: ```cpp drapableNode->getOrCreateStateSet()->setRenderBinDetails(10, "RenderBin"); drapableNode->getStateSet()->setAttributeAndModes(texture, osg::StateAttribute::ON); ``` ### 3. 处理VirtualProgram冲突 rex引擎会注入VirtualProgram(引用[1]),需保持shader兼容: ```cpp // 添加通用shader组件 VirtualProgram* vp = VirtualProgram::getOrCreate(drapableNode->getStateSet()); vp->addShader(new osg::Shader(osg::Shader::VERTEX, standardVertSource)); ``` ### 4. 调整渲染顺序 通过设置渲染分桶确保正确叠加: ```cpp // 地形层设置 terrainLayer->getStateSet()->setRenderBinDetails(5, "RenderBin"); // DrapableNode设置更高优先级 drapableNode->getStateSet()->setRenderBinDetails(6, "RenderBin"); ``` ### 5. 强制纹理绑定 在节点回调中显式绑定纹理: ```cpp drapableNode->addUpdateCallback(new osg::Callback{ virtual bool run(osg::Object* node, osg::Object* data) { osgEarth::Util::StateSetCache::get()->optimify(stateSet); return traverse(node, data); } }); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值