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);