You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OsgEarth自定义Widget去遮挡异常:背景与图像未隐藏

OsgEarth Declutter 功能:Widget 背景/图像不随文本隐藏的解决方案

问题根源

OsgEarth 的 Declutter 机制默认仅对 osgText::Text 类型的 Drawable 做隐藏处理,普通 Geometry(背景、图像)默认未被纳入遮挡隐藏逻辑,只会因视图缩放规则缩小,不会被隐藏。DEPTH_TEST 参数无效是因为 Declutter 机制本身会接管深度排序和可见性控制,单纯开关深度测试无法改变其默认行为。

解决方案

1. 使用 DeclutterGroup 统一管理 Widget 元素

将原来的 Geode 替换为 osgEarth::DeclutterGroup,该节点会自动管理组内所有 Drawable 的遮挡逻辑,确保重叠时所有元素同步隐藏。

2. 给背景/图像 Drawable 配置 Declutter 属性

对背景和图像的 Geometry 做以下设置:

  • 禁用显示列表:drawable->setUseDisplayList(false),确保 Declutter 能动态修改元素可见性。
  • 关闭 DEPTH_TEST 并启用混合模式:Widget 通常为半透明,需设置正确的 BlendFunc 避免渲染异常。
  • 设置统一的 Declutter 优先级:让背景、图像和文本使用相同的优先级,确保重叠时整体隐藏。

3. 代码修改示例

// 替换原Geode为DeclutterGroup
osg::ref_ptr<osgEarth::DeclutterGroup> declutterGroup = new osgEarth::DeclutterGroup();

// --- 配置背景Geometry ---
osg::ref_ptr<osg::Geometry> bgGeom = createBackgroundGeometry(); // 你的背景创建函数
osg::StateSet* bgSS = bgGeom->getOrCreateStateSet();
bgSS->setAttributeAndModes(new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA), osg::StateAttribute::ON);
bgSS->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
// 设置与文本一致的优先级(数值越小,优先级越高,越不易被隐藏)
bgSS->setAttributeAndModes(new osgEarth::Symbology::DeclutterPriority(50), osg::StateAttribute::ON);
bgGeom->setUseDisplayList(false);
declutterGroup->addDrawable(bgGeom);

// --- 配置图像Geometry ---
osg::ref_ptr<osg::Geometry> imgGeom = createImageGeometry(); // 你的图像创建函数
osg::StateSet* imgSS = imgGeom->getOrCreateStateSet();
imgSS->setAttributeAndModes(new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA), osg::StateAttribute::ON);
imgSS->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
imgSS->setAttributeAndModes(new osgEarth::Symbology::DeclutterPriority(50), osg::StateAttribute::ON);
imgGeom->setUseDisplayList(false);
declutterGroup->addDrawable(imgGeom);

// --- 配置文本元素 ---
for (auto& text : yourTextList) { // yourTextList是你的三个osgText对象集合
    osg::StateSet* textSS = text->getOrCreateStateSet();
    textSS->setAttributeAndModes(new osgEarth::Symbology::DeclutterPriority(50), osg::StateAttribute::ON);
    text->setUseDisplayList(false);
    declutterGroup->addDrawable(text);
}

// 将DeclutterGroup添加到AnnotationGroup
yourAnnotationGroup->addChild(declutterGroup); // yourAnnotationGroup是你的AnnotationGroup对象

4. 额外检查项

  • 确保你的 AnnotationGroup 已经正确启用 Declutter 功能:比如通过 osgEarth::AnnotationOptions 开启,或者父节点是 DeclutterNode。
  • 如果使用自定义的 DeclutterNode,需手动调用 declutterNode->addDrawable() 将所有 Widget 元素注册进去,替代 DeclutterGroup 的方式。

内容的提问来源于stack exchange,提问作者Marco Maisano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 02:18:20