osgEarth的hover拣选效果

12 篇文章 1 订阅
3 篇文章 0 订阅

目录

前言

一、关键代码


前言

前一篇文章有提到利用着色器,实现GeoNode颜色的改变,这篇文章主要是根据osgEarth的一个例子改进,实现鼠标在矢量要素上的一个hover拣选效果。


效果如下:

一、关键代码

shader:

const char* highlight_shader = R"(
    #pragma vp_function check_for_highlight, vertex_clip
    uniform uint objectid_to_highlight;
    uint oe_index_objectid;      // Stage global containing object id
    flat out int selected;
    void check_for_highlight(inout vec4 vertex)
    {
        selected = (objectid_to_highlight > 1u && objectid_to_highlight == oe_index_objectid) ? 1 : 0;
    }

    [break]
    #pragma vp_function highlight_fragment, fragment
    flat in int selected;
    void highlight_fragment(inout vec4 color)
    {
        if ( selected == 1 )
            color.rgb = vec3(0.2, 1.0, 1.0);
    }
)";

ViewPicker:

	struct ViewPicker
	{
		ViewPicker()
		: mapNode(nullptr)
		, picker(nullptr)
		, highlightUniform(nullptr)
		{ }

		osgEarth::MapNode* mapNode;
		osgEarth::Util::ObjectIDPicker* picker;
		osg::Uniform* highlightUniform;

		osg::ref_ptr<osgEarth::Feature> _pickedFeature;
		osg::ref_ptr<osgEarth::AnnotationNode> _pickedAnno;
		osg::ref_ptr<osg::Node> _pickedNode;
	};

 InitPicker:

void OsgEarthQtMainWindow::InitPicker(ViewPicker& Picker, osgViewer::View* pView, osgEarth::MapNode* pNode)
{
	// Highlight features as we pick'em.
	Picker.mapNode = pNode;
	InstallHighlighter(Picker);

	osgEarth::ObjectIDPicker::Function pick = [&](osgEarth::ObjectID id)
	{
		if (Picker.picker == Picker2D.picker)
		{
			Picker3D._pickedFeature = nullptr;
			Picker3D._pickedAnno = nullptr;
			Picker3D._pickedNode = nullptr;
			Picker3D.highlightUniform->set(0u);
		}
		else
		{
			Picker2D._pickedFeature = nullptr;
			Picker2D._pickedAnno = nullptr;
			Picker2D._pickedNode = nullptr;
			Picker2D.highlightUniform->set(0u);
		}
		if (id > 0)
		{
			// Got a pick:
			osgEarth::FeatureIndex* index = osgEarth::Registry::objectIndex()->get<osgEarth::FeatureIndex>(id).get();
			osgEarth::Feature* feature = index ? index->getFeature(id) : 0L;
			Picker._pickedFeature = feature;
			Picker._pickedAnno = osgEarth::Registry::objectIndex()->get<osgEarth::AnnotationNode>(id).get();
			Picker._pickedNode = osgEarth::Registry::objectIndex()->get<osg::Node>(id).get();
			Picker.highlightUniform->set(id);
		}
		else
		{
			// No pick:
			Picker._pickedFeature = nullptr;
			Picker._pickedAnno = nullptr;
			Picker._pickedNode = nullptr;
			Picker.highlightUniform->set(0u);
		}
	};

	Picker.picker = new osgEarth::ObjectIDPicker();
	Picker.picker->setView(pView);
	Picker.picker->setGraph(pNode);
	Picker.mapNode->addChild(Picker.picker);

	// Call our handler when hovering over the map
	Picker.picker->onHover(pick);
}

 InstallHighlighter:

void OsgEarthQtMainWindow::InstallHighlighter(ViewPicker& viewPicker)
{
	osg::StateSet* stateSet = viewPicker.mapNode->getOrCreateStateSet();
	int attrLocation = osgEarth::Registry::objectIndex()->getObjectIDAttribLocation();

	// This shader program will highlight the selected object.
	osgEarth::VirtualProgram* vp = osgEarth::VirtualProgram::getOrCreate(stateSet);
	osgEarth::ShaderLoader::load(vp, highlight_shader);

	// Since we're accessing object IDs, we need to load the indexing shader as well:
	osgEarth::Registry::objectIndex()->loadShaders(vp);

	// A uniform that will tell the shader which object to highlight:
	viewPicker.highlightUniform = new osg::Uniform("objectid_to_highlight", 0u);
	stateSet->addUniform(viewPicker.highlightUniform);
}

实例化 ViewPicker然后调用InitPicker即可,如下:

 

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值