osgEarth的Rex引擎原理分析(九十三)rex在渲染时会不会纹理单元内容频繁更改

本文分析了osgEarth的Rex引擎在渲染过程中纹理单元内容的频繁更改,指出这会导致CPU和GPU占用率升高。每个图层和瓦片在绘制时都需要向显存上传数据,尤其是瓦片的纹理数据,这种频繁上传是资源消耗的一个重要原因。

目标:(九十一)中的问题173

答案:会的,这是rex引擎启动后cpu、gpu占用率高的一个原因。

1、每一个图层(影像层、高层)在绘制时会往显存上传数据

osgEarthDrivers/engine_rex/LayerDrawable.cpp
void
LayerDrawable::drawImplementation(osg::RenderInfo& ri) const
{
    if (_layer)
    {
        if (ds._layerUidUL >= 0)
            ds._ext->glUniform1i(ds._layerUidUL,      (GLint)_layer->getUID());
        if (ds._layerOpacityUL >= 0 && _visibleLayer)
            ds._ext->glUniform1f(ds._layerOpacityUL,  (GLfloat)_visibleLayer->getOpacity());
        if (ds._layerMinRangeUL >= 0 && _imageLayer)
            ds._ext->glUniform1f(ds._layerMinRangeUL, (GLfloat)_imageLayer->getMinVisibleRange());
        if (ds._layerMaxRangeUL >= 0 && _imageLayer)
            ds._ext->glUniform1f(ds._layerMaxRangeUL, (GLfloat)_imageLayer->getMaxVisibleRange());
    }
}

2、每一个瓦片在绘制时,会往显存上传数据,包括往纹理单元上传纹理数据,如果瓦片很多,这种上传是很频繁的。

osgEarthDrivers/engine_rex/DrawTileCommand.cpp
void
DrawTileCommand::draw(osg::RenderInfo& ri, DrawState& dsMaster, osg::Referenced* layerData) const
{
    ds._ext->glUniform4fv(ds._tileKeyUL, 1, _keyValue.ptr());
    ds._ext->glUniform1i(ds._layerOrderUL, (GLint)_order);
    ds._ext->glUniform2fv(ds._elevTexelCoeffUL, 1, _elevTexelCoeff.ptr());
    ds._ext->glUniform2fv(ds._morphConstantsUL, 1, _morphConstants.ptr());

    state.setActiveTextureUnit((*dsMaster._bindings)[s].unit());
    sampler._texture->apply(state);

    ds._ext->glUniformMatrix4fv(samplerState._matrixUL, 1, GL_FALSE, sampler._matrix.ptr());
    ds._ext->glUniform1f(ds._parentTextureExistsUL, sampler._texture.valid() ? 1.0f : 0.0f);

    state.setActiveTextureUnit((*dsMaster._bindings)[s].unit());
    sampler._texture->apply(state);
}

待继续分析列表:

9、earth文件中都有哪些options((九)中问题)

10、如何根据earth文件options创建不同的地理信息引擎节点((九)中问题)

11、rex地理信息引擎的四梁八柱((九)中问题)

12、osgEarth::TerrainEngineNode中setMap方法作用((十二)中问题)

<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、付费专栏及课程。

余额充值