osg第29讲(hud菜单)

  1. 由上一讲学会了如何使用hud相机,而菜单也刚好是贴在屏幕之上,故可以用hud相机来实现菜单。我们只需要写一个事件接收器,判断鼠标的点击范围即可触发自己想要实现的方法。
//创建hud相机的Menu
osg::Camera* createHudMenu()
{
	osg::ref_ptr<osg::Camera>camera = new osg::Camera;
	camera->setViewMatrix(osg::Matrix::identity());//相机设置为单位矩阵
	camera->setRenderOrder(osg::Camera::POST_RENDER);
	camera->setClearMask(GL_DEPTH_BUFFER_BIT);//清除深度缓存
	camera->setAllowEventFocus(false);//不接受焦点
	camera->setViewport(200, 200, 200, 200);
	camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);//设置为绝对帧,防止拣选
	camera->setProjectionMatrixAsOrtho2D(0, 200, 0, 200);//正视投影的大小

														 //添加文字
	osg::ref_ptr<osg::Geode>geo = new osg::Geode;
	geo->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
	osg::ref_ptr<osgText::Text> text = new osgText::Text;
	geo->addDrawable(text);
	text->setFont("fonts/ZhanKuWenYiTi-2.ttf");
	text->setCharacterSize(50);//字体大小
	text->setText(L"测试");
	text->setPosition(osg::Vec3d(0, 50, 0));
	camera->addChild(geo);

	//添加纹理
	osg::Geometry*gm = new osg::Geometry;
	//设置顶点坐标
	osg::Vec3Array*vertex = new osg::Vec3Array;
	vertex->push_back(osg::Vec3d(0, 0, -1.0));
	vertex->push_back(osg::Vec3d(100, 0, -1.0));
	vertex->push_back(osg::Vec3d(100, 100, -1.0));
	vertex->push_back(osg::Vec3d(0, 100, -1.0));
	gm->setVertexArray(vertex);
	//设置法线
	osg::Vec3dArray*norm = new osg::Vec3dArray;
	norm->push_back(osg::Vec3(0.0, 0.0, 1.0));
	gm->setNormalArray(norm);
	gm->setNormalBinding(osg::Geometry::BIND_OVERALL);
	osg::Vec4dArray*arr_color = new osg::Vec4dArray;
	arr_color->push_back(osg::Vec4d(1.0,0.0,0.0,0.5));
	gm->setColorArray(arr_color);
	gm->setColorBinding(osg::Geometry::BIND_OVERALL);
	gm->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
	geo->addDrawable(gm);
	return camera.release();
}
class menuEvent:public osgGA::GUIEventHandler
{
public:
	menuEvent(osgViewer::Viewer*view_)
	{
		view = view_;
	}
	bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
	{
		if (!view)
		{
			return false;
		}
		switch (ea.getEventType())
		{
		case osgGA::GUIEventAdapter::PUSH:
		{
			if (ea.getX()>200&&ea.getX()<400&& ea.getY()>200 && ea.getY()<400)//根据菜单的位置触发事件
			{
				std::cout << "菜单触发";
			}	
		}
			break;
		default:
			break;
		}
		return false;
	}
private:
	osgViewer::Viewer*view;
};

我们可以看到,menu的代码和hud相机的实现一模一样,在事件接收器中判断鼠标位置,从而触发事件,前几讲有说到过事件接收器的实现,操作系统把事件给到osg,osg把事件压入队列,然后每一帧遍历事件接收器,触发handle(),如果在handle()中返回true则不再进行下一个事件消息,即如果此处返回true,我们的场景拖动就会无响应,需要返回false则继续下一个事件接收器。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值