先放一張圖看看效果:左上角就是這次做的圖例,很簡單的圖形,但是還花了我大半天,有一個小細節忽略了,后面講。
第一步是hudCamera的創建——
osg::Camera* CreateHudCamera() { osg::Camera* hudCamera = new osg::Camera; hudCamera->setProjectionMatrix(osg::Matrix::ortho2D(0,1280,0,800)); //投影矩陣-屏幕大小(一般) hudCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); //視圖矩陣-絕對幀引用 hudCamera->setViewMatrix(osg::Matrix::identity()); hudCamera->setClearMask(GL_DEPTH_BUFFER_BIT); //清除深度緩存 hudCamera->setRenderOrder(osg::Camera::POST_RENDER); //設置渲染順序-POST hudCamera->setAllowEventFocus(false); //設置事件焦點-false return hudCamera; }
HUD的創建我從書上看的,以下是部分摘抄:
在創建HUD進行文字顯示時,需要注意以下幾點:
渲染順序設置為POST,否則可能會被場景中的其他圖形所覆蓋;
注意關閉光照和深度;
投影矩陣通常設置為屏幕尺寸大小。
第二步是StateSet的設置和圖形、文本的繪制——
osg::Group* getLegend() { osg::Camera* hudCamera = this->CreateHudCamera(); osg::Geode* pGeode = new osg::Geode; osg::StateSet* pStateSet = pGeode->getOrCreateStateSet(); pStateSet->setMode(GL_LIGHTING,osg::StateAttribute::OFF); pStateSet->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF); osgText::Font* pFont = new osgText::Font; pFont = osgText::readFontFile("simhei.ttf"); float interval = (m_vMax - m_vMin) / 10.0f; //m_vMax m_vMin分別是標注屬性的最大值 最小值 for(int i=0; i<10; i++) { float nLeft = m_vMin + i * interval; float nRight = m_vMin + (i+1) * interval; float nMiddle = (nLeft + nRight) / 2.0f; //繪制矩形 osg::Geometry* pGeo = new osg::Geometry; osg::ref_ptr<osg::Vec4Array> colorArray = new osg::Vec4Array; pGeo = osg::createTexturedQuadGeometry(osg::Vec3(10,750.0f-(17*i),-1),osg::Vec3(38,0.0,0.0),osg::Vec3(0.0,15.0,0.0)); colorArray->push_back(this->getColor(nMiddle)); //getColor是根據屬性值計算顏色值的函數,需自行定義 pGeo->setColorArray(colorArray.get()); pGeo->setColorBinding(osg::Geometry::BIND_OVERALL); pGeode->addDrawable(pGeo); //float 轉 string,標注文本 char buffer[20]; sprintf_s(buffer,"%f",nLeft); string str = buffer; str += " - "; sprintf_s(buffer,"%f",nRight); str += buffer; //繪制文本 osgText::Text* pText = new osgText::Text; pText->setFont(pFont); pText->setText(str); pText->setPosition(osg::Vec3(52.0f,752.0f-(17*i),-1)); pText->setCharacterSize(15.0f); pText->setColor(osg::Vec4(199,77,15,1)); pGeode->addDrawable(pText); } osg::Group* pGroup = new osg::Group; hudCamera->addChild(pGeode); pGroup->addChild(hudCamera); return pGroup; }
StateSet的設置有兩項,關閉光照、關閉深度緩存。
圖形的繪制這里采用的是osg::createTexturedQuadGeometry()函數的詳細可以參考博客,提醒一下特別注意寬高與坐標軸的對應關系,我之前就弄成了水平面,又因為是HUD,根本看不到圖形。
至於文本的繪制就相對簡單了,這里不贅述了。
總之,就是根據要繪制的圖例項,逐項進行繪制,另外注意細節位置的調整,基本就完成了。