OSG实现类似arcgis中制图的图例效果

主要是通过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<osg::Node> FloodForm::createLegend()
{
    //图例面板背景颜色
    osg::ref_ptr<osg::Geometry>geometry=new osg::Geometry;
    osg::ref_ptr<osg::Vec4Array>colorArray=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_ptr<osg::Geometry>geometry1=new osg::Geometry;
    osg::ref_ptr<osg::Vec4Array>colorArray1=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_ptr<osg::Geometry>geometry2=new osg::Geometry;
    osg::ref_ptr<osg::Vec4Array>colorArray2=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_ptr<osg::Geometry>geometry3=new osg::Geometry;
    osg::ref_ptr<osg::Vec4Array>colorArray3=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;
}

 

createTexturedQuadGeometry函数解析

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没有用到就暂没有深究)

截部分图,最终效果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章