HUD,是head up displays的缩写。意思是显示的内容,始终朝着显示器方向。
在OSG中,HUD的实现是通过Camera类来实现的,而Camera类本身其实就是一个Transform,只是Camera的一些参数设置比较特殊罢了。
下面是Camera的一个继承图。它和之前用到的MatrixTransform一样,继承自Transform,之前的MatrixTransform可以用来对物体进行平移、旋转和缩放。
所以Camera其实也就是对物体变换,所有通过addChild,加到Camera下面作为孩子的Node,都会受到Camera的变换矩阵的影响。
但是Camera还有几个自己的类成员,这就是OpenGL的视图矩阵,投影矩阵和视口。这些东西最终决定我们在屏幕上看到的物体的位置,大小等。
所以对于Camera的使用,和MatrixTransform一样,设置好变换矩阵之后,然后把想要变换的东西,作为孩子,放置到Camera中即可。
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Geode>
#include <osg/Camera>
#include <osgText/Text>
osg::Camera* createHUD()
{
<span style="white-space:pre"> </span>// create a camera to set up the projection and model view matrices, and the subgraph to draw in the HUD
<span style="white-space:pre"> </span>osg::Camera* camera = new osg::Camera;
<span style="white-space:pre"> </span>// set the projection matrix
<span style="white-space:pre"> </span>camera->setProjectionMatrix(osg::Matrix::ortho2D(0, 1280, 0, 1024));
<span style="white-space:pre"> </span>// set the view matrix
<span style="white-space:pre"> </span>camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
<span style="white-space:pre"> </span>camera->setViewMatrix(osg::Matrix::identity());
<span style="white-space:pre"> </span>// only clear the depth buffer
<span style="white-space:pre"> </span>camera->setClearMask(GL_DEPTH_BUFFER_BIT);
<span style="white-space:pre"> </span>// draw subgraph after main camera view.
<span style="white-space:pre"> </span>camera->setRenderOrder(osg::Camera::POST_RENDER);
<span style="white-space:pre"> </span>// we don't want the camera to grab event focus from the viewers main camera(s).
<span style="white-space:pre"> </span>camera->setAllowEventFocus(false);
<span style="white-space:pre"> </span>//创建HUD文本
<span style="white-space:pre"> </span>osgText::Text* text = new osgText::Text;
<span style="white-space:pre"> </span>std::string timesFont("fonts/arial.ttf");
<span style="white-space:pre"> </span>text->setFont(timesFont);
<span style="white-space:pre"> </span>osg::Vec3 position(150.0f, 800.0f, 0.0f);
<span style="white-space:pre"> </span>text->setPosition(position);
<span style="white-space:pre"> </span>text->setText("Head Up Displays are simple :-)");
<span style="white-space:pre"> </span>//osgText本身不能被加到场景中,所以搞一个Geode。
<span style="white-space:pre"> </span>osg::Geode* geode = new osg::Geode();
<span style="white-space:pre"> </span>geode->addDrawable(text);
<span style="white-space:pre"> </span>//将文本放置到HUD变换的camera中
<span style="white-space:pre"> </span>camera->addChild(geode);
<span style="white-space:pre"> </span>return camera;
}
int main(int argc, char **argv)
{
<span style="white-space:pre"> </span>osgViewer::Viewer viewer;
<span style="white-space:pre"> </span>//创建一个模型,来与HUD形成对比
<span style="white-space:pre"> </span>osg::ref_ptr<osg::Node> cow = osgDB::readNodeFile("cow.osg");
<span style="white-space:pre"> </span>osg::ref_ptr<osg::Group> root = new osg::Group;
<span style="white-space:pre"> </span>root->addChild(cow.get());
<span style="white-space:pre"> </span>// add the HUD subgraph.
<span style="white-space:pre"> </span>root->addChild(createHUD());
<span style="white-space:pre"> </span>// set the scene to render
<span style="white-space:pre"> </span>viewer.setSceneData(root.get());
<span style="white-space:pre"> </span>return viewer.run();
}
上面代码,main函数,就是创建一头牛,一个hud,然后加载到场景中。
createHUD中则创建了一个Camera,一个Geode。先设置好Camera的一些参数,然后将Geode设置好文本内容后,加到Camera中,作为孩子。
所以,HUD其实就是一个特殊的Camera。