OSG HUD实现类似ArcGIS制图中图例效果(色块+标注)
先放一张图看看效果:左上角就是这次做的图例,很简单的图形,但是还花了我大半天,有一个小细节忽略了,后面讲。
第一步是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,根本看不到图形。
至于文本的绘制就相对简单了,这里不赘述了。
总之,就是根据要绘制的图例项,逐项进行绘制,另外注意细节位置的调整,基本就完成了。