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,根本看不到圖形。

  至於文本的繪制就相對簡單了,這里不贅述了。

  總之,就是根據要繪制的圖例項,逐項進行繪制,另外注意細節位置的調整,基本就完成了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM