使用OpenSceneGraph (osg)实现一个星系漫游

简介

使用OpenSceneGraph (osg)实现了一个太阳系漫游的程序,具有以下特点:

1.通过按键控制飞行器前进后退、空间姿态;

2.星系渲染;

3.背景星空渲染;

效果

提供了一张超大的星空背景图

代码示例
复制代码
int main(int argc, char *argv[])
{
    // 创建场景根节点
    osg::ref_ptr<osg::Group> root = new osg::Group;
    root->addChild(createSun());
    root->addChild(createMercury());
    root->addChild(createVenus());
    root->addChild(createEarth());
    root->addChild(createMars());
    root->addChild(createJupiter());
    root->addChild(createSaturn());
    root->addChild(createUranus());
    root->addChild(createNeptune());

    root->addChild(createSkyBox());

    osg::ref_ptr<osg::MatrixTransform> airplaneTransform = new osg::MatrixTransform;
    osg::Vec3 craftPos(0, -40, 0);
    airplaneTransform->addChild(createAircraft()); // 或加载外部模型
    root->addChild(airplaneTransform);

    osgViewer::Viewer viewer;
    viewer.setSceneData(root.get());

    AircraftController* ac=new AircraftController(airplaneTransform.get());
    ac->setViewer(&viewer);
    ac->initCamera(craftPos);
    viewer.addEventHandler(ac);
    viewer.setUpViewInWindow(100, 100, 1200, 1000);

    // 2. 创建 HUD 相机
    osg::Camera* hudCamera = createHUDCamera(1200, 1000); // 假设窗口大小为 1280x720
    osg::ref_ptr<osg::Geode> hudGeode = new osg::Geode;

    // // 3. 添加状态文字到 HUD
    osgText::Text* statusText = createStatusText("", 1200, 20); // 右下角位置
    AircraftHudTextCallback* acHudCb=new AircraftHudTextCallback(airplaneTransform.get());
    statusText->setUpdateCallback(acHudCb);
    hudGeode->addDrawable(statusText);
    hudCamera->addChild(hudGeode);

    // 4. 将 HUD 相机添加到场景
    root->addChild(hudCamera);
    // viewer.setLightingMode( osg::View::SKY_LIGHT );
    while(!viewer.done())
	{
        viewer.frame();
    } 
    // return viewer.run();
}

osg::ref_ptr<osg::Node> createSun()
{
    osg::ref_ptr<osg::Sphere> sphere = new osg::Sphere(osg::Vec3(0, 0, 0), 1);
    osg::ref_ptr<osg::ShapeDrawable> sphereDrawable = new osg::ShapeDrawable(sphere);
    sphereDrawable->setColor(osg::Vec4(1.0, 0.6, 0.4, 1.0));
    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    geode->addDrawable(sphereDrawable);
    // 加载纹理
    // 设置渲染状态
    osg::ref_ptr<osg::StateSet> stateSet = geode->getOrCreateStateSet();
    stateSet->setTextureAttributeAndModes(0, create_texture("sun.jpg"));
    // 创建 MatrixTransform 节点
    osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;

    // 将球体添加到变换节点
    transform->addChild(geode);

    // 创建回调并附加到变换节点
    transform->setUpdateCallback(new SpinCallback(0.001*velocityRate,osg::Vec3(0, 0, 1)));
    return transform;
}

osg::ref_ptr<osg::Node> createJupiter()
{
    std::string name="Jupiter";
    osg::ref_ptr<osg::Sphere> sphere =new osg::Sphere(osg::Vec3(0, 0, 0), get_param(name,"size"));
    osg::ref_ptr<osg::ShapeDrawable> sphereDrawable = new osg::ShapeDrawable(sphere);
    sphereDrawable->setColor(osg::Vec4(0.95, 0.86, 0.54, 1.0));
    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    geode->addDrawable(sphereDrawable);
    // 加载纹理
     // 设置渲染状态
    osg::ref_ptr<osg::StateSet> stateSet = geode->getOrCreateStateSet();
    stateSet->setTextureAttributeAndModes(0, create_texture("jupiter.jpg"));


    //
    double inner_radius=3/1.8*get_param(name,"size");
    double outer_radius=4.2/1.8*get_param(name,"size");
    osg::ref_ptr<osg::Geometry> ringGeometry=createRingGeometry(inner_radius,outer_radius,64);
    // ringGeometry->setColor(osg::Vec4(0.95, 0.86, 0.54, 0.9));
    osg::ref_ptr<osg::Geode> geode2=new osg::Geode;
    geode2->addDrawable(ringGeometry);

    osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
    transform->addChild(geode);
    transform->addChild(geode2);

    OrbitAndSpinCallback* cb=new OrbitAndSpinCallback();
    cb->setInit(get_param(name,"leanAngle"),osg::Vec3(0,1,0));
    cb->setOrbit(get_param(name,"orbitAngleVelocity"),get_param(name,"orbitRadius"),osg::Vec3(0, 0, 1.0));
    cb->setSpin(get_param(name,"spinAngleVelocity"),osg::Vec3(tan(get_param(name,"leanAngle")), 0, 1));

    transform->setUpdateCallback(cb);
    osg::ref_ptr<osg::Group> group = new osg::Group;
    group->addChild(createMoon("Lo",cb));
    group->addChild(createMoon("Europa",cb));
    group->addChild(createMoon("Callisto",cb));
    group->addChild(createMoon("Ganymede",cb));
    group->addChild(transform);
    print_plannet_info(name);
    return group;    
}
资源链接

http://antown.net/item_introduction/solarsystem

相关推荐
扶尔魔ocy1 天前
【qt openGL入门笔记】windows编译MinGW版本的osgearth(2.10.1)
qt·opengl·osg
扶尔魔ocy2 天前
【QT OpenGL】知识点编目及传送门
qt·opengl·osg
扶尔魔ocy15 天前
【qt openGL入门笔记】OSG实现飞机模型在网格图上飞行并进行态势标绘(四)
qt·opengl·osg
扶尔魔ocy17 天前
【qt openGL入门笔记】OSG实现显示飞机模型飞行的点迹(二)
qt·opengl·osg
扶尔魔ocy17 天前
【qt openGL入门笔记】OSG实现飞机模型在网格图上飞行(三)
opengl·osg
扶尔魔ocy18 天前
【qt openGL入门笔记】OSG实现飞机模型在网格图上飞行
qt·opengl·osg
directx3d_beginner8 个月前
10,cookbook的lod示例
osg
directx3d_beginner8 个月前
8,将0级简模文件和精模文件同时放入pagedlod
osg
directx3d_beginner8 个月前
9,0级建模文件和0级精模文件写成根节点
osg
directx3d_beginner8 个月前
5,保存4个一级节点
osg