osg中实现HUD(OSG初级篇1)

HEAD-UP DISPLAY, 即是抬头显示功能,在opengl编程中,我们有时需要一种屏幕区域,这个区域并不会随着三维场景视角表换而发生改变,也可以讲,是在三维场景中实现了一个二维子场景,故常用来显示提示信息。下面这个小例子实现了GL3版本中的HUD功能(OSG编译选项里面,我们选择了编译GLcore版本,因为我们想要这个功能应用在osgEarth3.0以后的版本中,不熟悉什么叫GLCore的童靴可以参考我的另一篇博文《opengl版本发展史及各种概念的厘清》)。

首先,我们要创建一个相机

    osg::Camera* camera = new osg::Camera;
    camera->setName("Hud Camera");
    // set the projection matrix
    camera->setProjectionMatrixAsOrtho2D(0, screen_width, 0, screen_heigh);
    camera->setViewport(0, 0, screen_width, screen_heigh);
    // set the view matrix
    camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
    camera->setViewMatrix(osg::Matrix::identity());
    camera->setClearColor(osg::Vec4(1, 0.5, 0.5, 0.5));

将相机的投影方式设置为正射投影(Ortho2D);视口设置为屏幕大小;现在我们看到的界面是整个屏幕;设置参考帧为绝对。

创建完了相机,接下来我们创建要在屏幕上显示的内容。一般情况下我们会创建一个矩形,在这个矩形上贴纹理,或绘制图案,作为HUD的显示内容,下面的代码,创建一个白色的矩形。


osg::Geometry* createQuad(int screen_width, int screen_heigh, float z) {
    osg::Geometry* polyGeom = new osg::Geometry();
    polyGeom->setSupportsDisplayList(false);
    osg::Vec3Array* vertices = new osg::Vec3Array;
    osg::Vec2Array* texcoords = new osg::Vec2Array;
    osg::Vec4Array* colors = new osg::Vec4Array;

    /*four vertex*/
    vertices->push_back(osg::Vec3d(0, 0, z));
    texcoords->push_back(osg::Vec2f(0, 0));

    vertices->push_back(osg::Vec3d(screen_width, 0, z));
    texcoords->push_back(osg::Vec2f(1, 0));

    vertices->push_back(osg::Vec3d(screen_width, screen_heigh, z));
    texcoords->push_back(osg::Vec2f(1, 1));

    vertices->push_back(osg::Vec3d(0, screen_heigh, z));
    texcoords->push_back(osg::Vec2f(0, 1));
    /*four vertex*/
    colors->push_back(osg::Vec4f(1.0,1.0,1.0,1.0));
    colors->setBinding(osg::Array::BIND_OVERALL);

    /*set vertex array and tex coord array*/
    polyGeom->setVertexArray(vertices);
    polyGeom->setTexCoordArray(0, texcoords);
    polyGeom->setColorArray(colors);
    polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, 0, vertices->size()));
    return polyGeom;
}

创建一个viewer,并且取得窗口的宽高。

    // initialize a viewer:
    osgViewer::Viewer viewer;    
    viewer.setUpViewAcrossAllScreens();
    osgViewer::Viewer::Windows windows;
    viewer.getWindows(windows);
    int screen_width = windows[0]->getTraits()->width;
    int screen_heigh = windows[0]->getTraits()->height;

然后创建一个场景树中的叶子节点,将createQuad函数创建的矩形包含在geode中:

    /*create a geode*/
    osg::Geode* _geode = new osg::Geode();
    _geode->setName("GeodeOfHUD");
    osg::Geometry* polyGeom = createQuad(screen_width, screen_heigh, -100);
    polyGeom->setName("PolyGeomOfHUD_");
    _geode->addDrawable(polyGeom);

最后,我们将场景加入到view中

  camera->addChild(_geode);
  viewer.setSceneData(camera);

这样,我们就完成了整个HUD效果的创建。

完整的代码如下



osg::Geometry* createQuad(int screen_width, int screen_heigh, float z) {
    osg::Geometry* polyGeom = new osg::Geometry();
    polyGeom->setSupportsDisplayList(false);
    osg::Vec3Array* vertices = new osg::Vec3Array;
    osg::Vec2Array* texcoords = new osg::Vec2Array;
    osg::Vec4Array* colors = new osg::Vec4Array;

    /*four vertex*/
    vertices->push_back(osg::Vec3d(0, 0, z));
    texcoords->push_back(osg::Vec2f(0, 0));

    vertices->push_back(osg::Vec3d(screen_width, 0, z));
    texcoords->push_back(osg::Vec2f(1, 0));

    vertices->push_back(osg::Vec3d(screen_width, screen_heigh, z));
    texcoords->push_back(osg::Vec2f(1, 1));

    vertices->push_back(osg::Vec3d(0, screen_heigh, z));
    texcoords->push_back(osg::Vec2f(0, 1));
    /*four vertex*/
    colors->push_back(osg::Vec4f(1.0,1.0,1.0,1.0));
    colors->setBinding(osg::Array::BIND_OVERALL);

    /*set vertex array and tex coord array*/
    polyGeom->setVertexArray(vertices);
    polyGeom->setTexCoordArray(0, texcoords);
    polyGeom->setColorArray(colors);
    polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, 0, vertices->size()));
    return polyGeom;
}


int
main(int argc, char** argv)
{

    // initialize a viewer:
    osgViewer::Viewer viewer;
    /*得到窗口的宽高*/
    viewer.setUpViewAcrossAllScreens();
    osgViewer::Viewer::Windows windows;
    viewer.getWindows(windows);
    int screen_width = windows[0]->getTraits()->width;
    int screen_heigh = windows[0]->getTraits()->height;

    /*创建HUD相机*/
    osg::Camera* camera = new osg::Camera;
    camera->setName("Hud Camera");
    // set the projection matrix
    camera->setProjectionMatrixAsOrtho2D(0, screen_width, 0, screen_heigh);
    camera->setViewport(0, 0, screen_width, screen_heigh);
    // set the view matrix
    camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
    camera->setViewMatrix(osg::Matrix::identity());
    camera->setClearColor(osg::Vec4(1, 0.5, 0.5, 0.5));
    /*create quad with texture from rtt*/
    osg::Geode* _geode = new osg::Geode();
    _geode->setName("GeodeOfHUD");
    osg::Geometry* polyGeom = createQuad(screen_width, screen_heigh, -100);
    polyGeom->setName("PolyGeomOfHUD_");
    _geode->addDrawable(polyGeom);
    camera->addChild(_geode);
    viewer.setSceneData(camera);

    int r = viewer.run();
    return r;
}

 

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值