主要是通过osg的HUD来实现。
所谓HUD节点,就是无论三维场景怎么样变动,它都能在屏幕中固定的位置显示的节点,即不随场景和视点的变换而变换。
实现步骤:
1.创建相机,它的子节点绘制到这个HUD中
2.设置投影矩阵,这个就是投影到场景的屏幕上
3.设置相对帧setReferenceFrame(osg::Transform::ABSOLUTE_RF);camera-
>setViewMatrix(osg::Matrix::identity());这个保证这个节点不随着场景和视点的变换而变化
4.清除深度缓存
5.设置渲染顺序camera->setRenderOrder(osg::Camera::POST_RENDER);这个保证了最后
渲染,HUD一直在场景的最外面
6.camera->setAllowEventFocus(false);保证该HUD不接受事件
之后就是在HUD上添加色块和标注(色块是用Geometry绘制几何体,标注是osgText::Text)
核心代码实现如下:
//创建图例
osg::ref_ptr FloodForm::createLegend()
{
//图例面板背景颜色
osg::ref_ptrgeometry=new osg::Geometry;
osg::ref_ptrcolorArray=new osg::Vec4Array;
geometry=osg::createTexturedQuadGeometry(osg::Vec3(455.0f,5.0f,0.0f),
osg::Vec3(160.0f,0.0f,0.0f),osg::Vec3(0.0f,100.0f,0.0f));
colorArray->push_back(osg::Vec4(0.9,0.9,0.88,1.0f));
geometry->setColorArray(colorArray.get());
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
//绘制矩形
//低水位颜色表示
osg::ref_ptrgeometry1=new osg::Geometry;
osg::ref_ptrcolorArray1=new osg::Vec4Array;
geometry1=osg::createTexturedQuadGeometry(osg::Vec3(460.0f,50.0f,0.0f),
osg::Vec3(30.0f,0.0f,0.0f),osg::Vec3(0.0f,15.0f,0.0f));
colorArray1->push_back(osg::Vec4(1,0.89,0.76,1.0f)); //getColor是根据属性值计算颜色值的函数,需自行定义
geometry1->setColorArray(colorArray1.get());
geometry1->setColorBinding(osg::Geometry::BIND_OVERALL);
//中等水位颜色表示
osg::ref_ptrgeometry2=new osg::Geometry;
osg::ref_ptrcolorArray2=new osg::Vec4Array;
geometry2=osg::createTexturedQuadGeometry(osg::Vec3(460.0f,30.0f,0.0f),
osg::Vec3(30.0f,0.0f,0.0f),osg::Vec3(0.0f,15.0f,0.0f));
colorArray2->push_back(osg::Vec4(0.97,0.675,0.39,1.0f));
geometry2->setColorArray(colorArray2.get());
geometry2->setColorBinding(osg::Geometry::BIND_OVERALL);
//高等水位颜色表示
osg::ref_ptrgeometry3=new osg::Geometry;
osg::ref_ptrcolorArray3=new osg::Vec4Array;
geometry3=osg::createTexturedQuadGeometry(osg::Vec3(460.0f,10.0f,0.0f),
osg::Vec3(30.0f,0.0f,0.0f),osg::Vec3(0.0f,15.0f,0.0f));
colorArray3->push_back(osg::Vec4(0.94,0.46,0.02,1.0f)); //getColor是根据属性值计算颜色值的函数,需自行定义
geometry3->setColorArray(colorArray3.get());
geometry3->setColorBinding(osg::Geometry::BIND_OVERALL);
//文字
//图例
osgText::Text *text=new osgText::Text;
//设置字体
text->setFont("fonts/simhei.ttf");
//设置文字显示的位置
text->setPosition(osg::Vec3(460.0f,80.0f,0.0f));
text->setColor( osg::Vec4( 0, 0, 0, 1));
text->setText(L"图例");//设置显示的文字
text->setCharacterSize(16); //设置字体大小
//低水位
osgText::Text *text1=new osgText::Text;
//设置字体
text1->setFont("fonts/simhei.ttf");
//设置文字显示的位置
text1->setPosition(osg::Vec3(500.0f,50.0f,0.0f));
text1->setColor( osg::Vec4( 0, 0, 0, 1));
text1->setText(L"低等水位)");//设置显示的文字
text1->setCharacterSize(12); //设置字体大小
//中等水位
osgText::Text *text2=new osgText::Text;
//设置字体
text2->setFont("fonts/simhei.ttf");
//设置文字显示的位置
text2->setPosition(osg::Vec3(500.0f,30.0f,0.0f));
text2->setColor( osg::Vec4( 0, 0, 0, 1));
text2->setText(L"中等水位");//设置显示的文字
text2->setCharacterSize(12); //设置字体大小
//高水位
osgText::Text *text3=new osgText::Text;
//设置字体
text3->setFont("fonts/simhei.ttf");
//设置文字显示的位置
text3->setPosition(osg::Vec3(500.0f,10.0f,0.0f));
text3->setColor( osg::Vec4( 0, 0, 0, 1));
text3->setText(L"高等水位");//设置显示的文字
text3->setCharacterSize(12); //设置字体大小
//几何体节点
osg::Geode*geode=new osg::Geode();
geode->addChild(geometry);
geode->addChild(geometry1);
geode->addChild(geometry2);
geode->addChild(geometry3);
//将文字Text作这drawable加入到Geode节点中
geode->addDrawable(text); //图例
geode->addDrawable(text1); //将文字Text作这drawable加入到Geode节点中
geode->addDrawable(text2); //将文字Text作这drawable加入到Geode节点中
geode->addDrawable(text3); //将文字Text作这drawable加入到Geode节点中
//设置状态
osg::StateSet* stateset = geode->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);//关闭灯光
stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);//关闭深度测试
//打开GL_BLEND混合模式(以保证Alpha纹理正确)
stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
//相机
osg::Camera* camera = new osg::Camera;
//设置透视矩阵
camera->setProjectionMatrix(osg::Matrix::ortho2D(0,600,0,600));//正交投影
//设置绝对参考坐标系,确保视图矩阵不会被上级节点的变换矩阵影响
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
//视图矩阵为默认的
camera->setViewMatrix(osg::Matrix::identity());
//设置背景为透明,否则的话可以设置ClearColor
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
camera->setAllowEventFocus( false);//不响应事件,始终得不到焦点
//设置渲染顺序,必须在最后渲染
camera->setRenderOrder(osg::Camera::POST_RENDER);
camera->addChild(geode);//将要显示的Geode节点加入到相机
return camera;
}
OSG_EXPORT Geometry* osg::createTexturedQuadGeometry(const Vec3 & corner,const Vec3 & widthVec,const Vec3 & heightVec,float l,float b,float r,float t )
corner变量是起点,是从左下角起始的点,是这个起始点的世界坐标,从这个起点按照widthVec和heightVec来画出一个QUAD矩形,至于后面的l,b,r,t,似乎是和二维贴图有关的,也就是取贴图上的那一部分。(这里主要用到前面三个参数,后面的l,b,r,t没有用到就暂没有深究)
截部分图,最终效果如下: