主要是通過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沒有用到就暫沒有深究)
截部分圖,最終效果如下: