当前位置:网站首页>【osg】OSG开发(04)—创建多个场景视图

【osg】OSG开发(04)—创建多个场景视图

2022-06-23 22:34:00 iriczhao

一、开篇

在osg中,有时候需要使用到多个场景视图,每一个场景视图中有不一样的操作:例如:漫游器、照相机、粒子效果、多个模型组合等。

在OSG中,提供了osgViewer::CompositeViewer类来实现这个需求。

二、实现原理

(1)创建一个osgViewer::CompositeViewer实例
(2)使用osgViewer::View代表一个具体的View视图
(3)使用osgViewer::CompositeViewer的addView()方法将创建的osgViewer::View添加到osgViewer::CompositeViewer中

(2-1)首先读取一个模型文件:

osg::ref_ptr<osg::Node> scene = osgDB::readNodeFile("osgDatas/glider.osgt");

(2-2)创建一个osgViewer::CompositeViewer实例:

osgViewer::CompositeViewer viewer;

(2-3)创建一个osg::GraphicsContext::WindowingSystemInterface来获取窗口系统的信息,这里主要获取:主窗口id、长、宽等信息:

osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
if (!wsi)
{
    
    osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
    return 1;
}

unsigned int width, height;
osg::GraphicsContext::ScreenIdentifier main_screen_id;

main_screen_id.readDISPLAY();
main_screen_id.setUndefinedScreenDetailsToDefaultScreen();

//获取窗口的id号和对应的分辨率(长宽比)
wsi->getScreenResolution(main_screen_id, width, height);

(2-4)使用osg::GraphicsContext::Traits来创建一个窗口配置对象,最后使用osg::GraphicsContext的createGraphicsContext()创建显示图像的上下文:

osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->x = 100;
traits->y = 100;
traits->width = 1000;
traits->height = 800;
traits->windowDecoration = true;
traits->doubleBuffer = true;
traits->sharedContext = 0;
traits->readDISPLAY();
traits->setUndefinedScreenDetailsToDefaultScreen();

osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());

(2-5)创建四个视图

// 第一个视图
{
    
    osgViewer::View* view = new osgViewer::View;

    osg::ref_ptr<osg::Node> scene = osgDB::readNodeFile("osgDatas/fountain.osgt");

    view->setName("View three");
    viewer.addView(view);

    view->setSceneData(scene);

    view->getCamera()->setName("Cam three");
    view->getCamera()->setProjectionMatrixAsPerspective(30.0, double(traits->width) / double(traits->height/2), 1.0, 1000.0);
    view->getCamera()->setViewport(new osg::Viewport(0, traits->height/2, traits->width/2,traits->height/2));
    view->getCamera()->setGraphicsContext(gc.get());
    view->setCameraManipulator(new osgGA::TerrainManipulator);
}

// 第二个视图
{
    
    osgViewer::View* view = new osgViewer::View;
    view->setName("View two");

    osg::ref_ptr<osg::Node> scene = osgDB::readNodeFile("osgDatas/cow.osgt");
    viewer.addView(view);

    view->setSceneData(scene);
    view->getCamera()->setName("Cam two");
    view->getCamera()->setViewport(new osg::Viewport(traits->width/2, traits->height/2, traits->width/2,traits->height/2));
    view->getCamera()->setGraphicsContext(gc.get());
    view->setCameraManipulator(new osgGA::TerrainManipulator);

}

// 第三个视图
{
    
    osgViewer::View* view = new osgViewer::View;
    view->setName("View one");
    viewer.addView(view);

    view->setSceneData(scene);
    view->getCamera()->setName("Cam one");
    view->getCamera()->setViewport(new osg::Viewport(0,0, traits->width/2, traits->height/2));
    view->getCamera()->setGraphicsContext(gc.get());

    osg::ref_ptr<osgGA::StateSetManipulator> statesetManipulator = new osgGA::StateSetManipulator;
    statesetManipulator->setStateSet(view->getCamera()->getOrCreateStateSet());

    view->setCameraManipulator(new osgGA::TerrainManipulator);
    view->addEventHandler( statesetManipulator.get() );

    view->addEventHandler( new osgViewer::StatsHandler );
    view->addEventHandler( new osgViewer::HelpHandler );
    view->addEventHandler( new osgViewer::WindowSizeHandler );
    view->addEventHandler( new osgViewer::ThreadingHandler );
    view->addEventHandler( new osgViewer::RecordCameraPathHandler );
}


// 第四个视图
{
    
    osgViewer::View* view = new osgViewer::View;
    view->setName("View one");
    viewer.addView(view);

    view->setSceneData(scene);
    view->getCamera()->setName("Cam one");
    view->getCamera()->setViewport(new osg::Viewport(traits->width/2, 0, traits->width/2,traits->height/2));
    view->getCamera()->setGraphicsContext(gc.get());

    // 添加状态操作器
    osg::ref_ptr<osgGA::StateSetManipulator> statesetManipulator = new osgGA::StateSetManipulator;
    statesetManipulator->setStateSet(view->getCamera()->getOrCreateStateSet());

    view->setCameraManipulator(new osgGA::TerrainManipulator);
    view->addEventHandler( statesetManipulator.get() );

    view->addEventHandler( new osgViewer::StatsHandler );
    view->addEventHandler( new osgViewer::HelpHandler );
    view->addEventHandler( new osgViewer::WindowSizeHandler );
    view->addEventHandler( new osgViewer::ThreadingHandler );
    view->addEventHandler( new osgViewer::RecordCameraPathHandler );
}

四、效果

五、完整代码

#include <iostream>

#include <osgUtil/Optimizer>
#include <osgDB/ReadFile>

#include <osg/Material>
#include <osg/Geode>
#include <osg/BlendFunc>
#include <osg/Depth>
#include <osg/Projection>
#include <osg/PolygonOffset>
#include <osg/MatrixTransform>
#include <osg/Camera>
#include <osg/FrontFace>

#include <osgText/Text>

#include <osgGA/TerrainManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/StateSetManipulator>
#include <osgViewer/ViewerEventHandlers>

#include <osgViewer/CompositeViewer>

#include <osg/io_utils>

int main( int argc, char **argv )
{
    
    //读取模型文件
    osg::ref_ptr<osg::Node> scene = osgDB::readNodeFile("osgDatas/glider.osgt");

    //创建CompositeViewer
    osgViewer::CompositeViewer viewer;

    if (viewer.getNumViews()==0)
    {
    

        osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
        if (!wsi)
        {
    
            osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
            return 1;
        }

        unsigned int width, height;
        osg::GraphicsContext::ScreenIdentifier main_screen_id;

        main_screen_id.readDISPLAY();
        main_screen_id.setUndefinedScreenDetailsToDefaultScreen();
        wsi->getScreenResolution(main_screen_id, width, height);

        osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
        traits->x = 100;
        traits->y = 100;
        traits->width = 1000;
        traits->height = 800;
        traits->windowDecoration = true;
        traits->doubleBuffer = true;
        traits->sharedContext = 0;
        traits->readDISPLAY();
        traits->setUndefinedScreenDetailsToDefaultScreen();

        osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());

        // 第一个视图
        {
    
            osgViewer::View* view = new osgViewer::View;

            osg::ref_ptr<osg::Node> scene = osgDB::readNodeFile("osgDatas/fountain.osgt");

            view->setName("View three");
            viewer.addView(view);

            view->setSceneData(scene);

            view->getCamera()->setName("Cam three");
            view->getCamera()->setProjectionMatrixAsPerspective(30.0, double(traits->width) / double(traits->height/2), 1.0, 1000.0);
            view->getCamera()->setViewport(new osg::Viewport(0, traits->height/2, traits->width/2,traits->height/2));
            view->getCamera()->setGraphicsContext(gc.get());
            view->setCameraManipulator(new osgGA::TerrainManipulator);
        }

        // 第二个视图
        {
    
            osgViewer::View* view = new osgViewer::View;
            view->setName("View two");

            osg::ref_ptr<osg::Node> scene = osgDB::readNodeFile("osgDatas/cow.osgt");
            viewer.addView(view);

            view->setSceneData(scene);
            view->getCamera()->setName("Cam two");
            view->getCamera()->setViewport(new osg::Viewport(traits->width/2, traits->height/2, traits->width/2,traits->height/2));
            view->getCamera()->setGraphicsContext(gc.get());
            view->setCameraManipulator(new osgGA::TerrainManipulator);

        }

        // 第三个视图
        {
    
            osgViewer::View* view = new osgViewer::View;
            view->setName("View one");
            viewer.addView(view);

            view->setSceneData(scene);
            view->getCamera()->setName("Cam one");
            view->getCamera()->setViewport(new osg::Viewport(0,0, traits->width/2, traits->height/2));
            view->getCamera()->setGraphicsContext(gc.get());

            osg::ref_ptr<osgGA::StateSetManipulator> statesetManipulator = new osgGA::StateSetManipulator;
            statesetManipulator->setStateSet(view->getCamera()->getOrCreateStateSet());

            view->setCameraManipulator(new osgGA::TerrainManipulator);
            view->addEventHandler( statesetManipulator.get() );

            view->addEventHandler( new osgViewer::StatsHandler );
            view->addEventHandler( new osgViewer::HelpHandler );
            view->addEventHandler( new osgViewer::WindowSizeHandler );
            view->addEventHandler( new osgViewer::ThreadingHandler );
            view->addEventHandler( new osgViewer::RecordCameraPathHandler );
        }


        // 第四个视图
        {
    
            osgViewer::View* view = new osgViewer::View;
            view->setName("View one");
            viewer.addView(view);

            view->setSceneData(scene);
            view->getCamera()->setName("Cam one");
            view->getCamera()->setViewport(new osg::Viewport(traits->width/2, 0, traits->width/2,traits->height/2));
            view->getCamera()->setGraphicsContext(gc.get());

            // add the state manipulator
            osg::ref_ptr<osgGA::StateSetManipulator> statesetManipulator = new osgGA::StateSetManipulator;
            statesetManipulator->setStateSet(view->getCamera()->getOrCreateStateSet());

            view->setCameraManipulator(new osgGA::TerrainManipulator);
            view->addEventHandler( statesetManipulator.get() );

            view->addEventHandler( new osgViewer::StatsHandler );
            view->addEventHandler( new osgViewer::HelpHandler );
            view->addEventHandler( new osgViewer::WindowSizeHandler );
            view->addEventHandler( new osgViewer::ThreadingHandler );
            view->addEventHandler( new osgViewer::RecordCameraPathHandler );
        }

    }

    return viewer.run();
}

原网站

版权声明
本文为[iriczhao]所创,转载请带上原文链接,感谢
https://blog.csdn.net/iriczhao/article/details/125417764