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沒有用到就暫沒有深究)

截部分圖,最終效果如下:

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