实现HUD显示文字,osghud解析

OSG中的HUD

所谓HUD节点,说白了就是无论三维场景中的内容怎么改变,它都能在屏幕上固定位置显示的节点。

实现要点:
  • 不接受鼠标拖动事件
  • 关闭光照,不受场景光照影响,所有内容以同一亮度显示
  • 在其他相机的基础上渲染,关闭深度测试,不要清空颜色缓存
  • 调整渲染顺序,使它的内容最后绘制
  • 设定参考贴为绝对型:setReferenceFrame(osg::Transform:ABSOLUTE_RF)
  • 使其不受父节点变换的影响:setMatrix(osg::Matrix::identity())
  • 使用平行投影,设定虚拟投影窗口的大小,这个窗口的大小决定了后面绘制的图形和文字的尺度比例
示例代码:
    
   // 创建 HUD 摄像机
       osg :: ref_ptr < osg :: Camera > camera = new osg :: Camera ;
       camera -> setProjectionMatrix ( osg :: Matrix :: ortho2D (0, 1000, 0, 1000)); // 表示摄像机里的平面世界有多大
       camera -> setReferenceFrame ( osg :: Transform :: ABSOLUTE_RF );
       camera -> setViewMatrix ( osg :: Matrix :: identity ());

       camera -> setClearMask ( GL_DEPTH_BUFFER_BIT );
       camera -> setAllowEventFocus ( false );
       camera -> setRenderOrder ( osg :: Camera :: POST_RENDER );

       // 创建提示对象
       m_prompt = new osgText :: Text ;

       QFont f ( " 宋体 " );
       osgText :: Font * font = new osgText :: Font ( new osgQt :: QFontImplementation ( f ));

       m_prompt -> setFont ( font );
       m_prompt -> setCharacterSize (16);
       m_prompt -> setPosition ( osg :: Vec3 (0.0f, 10.0f, 0.0f));
       m_prompt -> setColor ( osg :: Vec4 (1, 1, 1, 1));
       m_prompt -> setDataVariance ( osg :: Object :: DYNAMIC );
       m_prompt -> setText ( _conv ( " 坐标 " ), osgText :: String :: ENCODING_UTF8 );

       osg :: ref_ptr < osg :: Geode > geode = new osg :: Geode ;
       geode -> addDrawable ( m_prompt );

       osg :: ref_ptr < osg :: StateSet > stateSet = geode -> getOrCreateStateSet ();
       stateSet -> setMode ( GL_LIGHTING , osg :: StateAttribute :: OFF );
       stateSet -> setMode ( GL_DEPTH_TEST , osg :: StateAttribute :: OFF );
       stateSet -> setMode ( GL_BLEND , osg :: StateAttribute :: ON );

       camera -> addChild ( geode );
 
       // 添加到场景里
       viewer->getSceneData()->asGroup()->addChild(camera);


除了使用相机,还可以使用MatrixTransfor节点和Projection节点来实现HUDText

osg::Node* createHUD()
{ // add a string reporting the type of winding rule tessellation applied
    osg::Geode* geode = new osg::Geode();

    std::string timesFont("fonts/arial.ttf");

    // turn lighting off for the text and disable depth test to ensure its always ontop.
    osg::StateSet* stateset = geode->getOrCreateStateSet();
    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);

    // Disable depth test, and make sure that the hud is drawn after everything
    // else so that it always appears ontop.
    stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
    stateset->setRenderBinDetails(11,"RenderBin");

    osg::Vec3 position(150.0f,900.0f,0.0f);
    osg::Vec3 delta(0.0f,-30.0f,0.0f);

    {
        osgText::Text* text = new  osgText::Text;
        geode->addDrawable( text );

        text->setFont(timesFont);
        text->setPosition(position);
        text->setText("Tessellation example - no tessellation (use 'W' wireframe to visualise)");
        text->setColor(osg::Vec4(1.0,1.0,0.8,1.0));
        position += delta;

    }
    {
        osgText::Text* text = new  osgText::Text;
        geode->addDrawable( text );

        text->setFont(timesFont);
        text->setPosition(position);
        text->setText("Press 'n' to use an alternative tessellation.");

    }

    // create the hud.
    osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
    modelview_abs->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
    modelview_abs->setMatrix(osg::Matrix::identity());
    modelview_abs->addChild(geode);

    osg::Projection* projection = new osg::Projection;
    projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
    projection->addChild(modelview_abs);

    return projection;

}

你可能感兴趣的:(实现HUD显示文字,osghud解析)