前言
osgearth_windows示例,展示了创建多个视景器,在不同的窗口或者再同一个窗口。
执行命令
// 创建两个 视口,独立的
osgearth_windowsd.exe earth_image\china-simple.earth --views 2
// 创建两个 独立的视口,并且共享上下文
osgearth_windowsd.exe earth_image\china-simple.earth --views 2 --shared
效果
两个视景器,在两个窗口,互相独立。
两个视景器,在同一个窗口,但操作器依然是互相独立。
代码分析
#include <osgViewer/CompositeViewer>
#include <osgEarth/Notify>
#include <osgEarthUtil/EarthManipulator>
#include <osgEarthUtil/ExampleResources>
#include <osgEarth/MapNode>
#include <osgEarth/ThreadingUtils>
#include <osgEarth/Metrics>
#include <iostream>
#define LC "[viewer] "
using namespace osgEarth;
using namespace osgEarth::Util;
int
usage(const char* name)
{
OE_NOTICE
<< "\nUsage: " << name << " file.earth"
<< "\n --views [num] : Number of windows to open" // 打开窗口的个数
<< "\n --shared : Use a shared graphics context" // 是否共享图形设备上下文
<< "\n"
<< MapNodeHelper().usage() << std::endl;
return 0;
}
int
main(int argc, char** argv)
{
osg::ArgumentParser arguments(&argc,argv);
// help?
if ( arguments.read("--help") )
return usage(argv[0]);
// 创建视景器的个数,默认情况1个
int numViews = 1;
arguments.read("--views", numViews);
// 是否共享图形设备
bool sharedGC;
sharedGC = arguments.read("--shared");
// create a viewer:
osgViewer::CompositeViewer viewers(arguments);// 根据参数,创建多视景器
viewers.setThreadingModel(viewers.SingleThreaded);// 设置单线程
osg::Node* node = MapNodeHelper().load(arguments, &viewers);
if (!node)
return usage(argv[0]);
// 宽度
int size = 500;
for(int i=0; i<numViews; ++i)
{
osgViewer::View* view = new osgViewer::View();
int width = sharedGC? size*numViews : size;// 如果共享,则视口尺寸宽度变大
view->setUpViewInWindow(10+(i*size+30), 10, width, size);// 设置view在设备窗口的位置,左上角为(0,0)点
view->setCameraManipulator(new EarthManipulator(arguments));// 设置相机操作器
view->setSceneData(node);
view->getDatabasePager()->setUnrefImageDataAfterApplyPolicy( true, false );// 不太理解这个函数的意义
if (sharedGC)
{
// 如果是共享的情况,需要单独设置视口、透视投影。
view->getCamera()->setViewport(i*size, 0, size, size);
view->getCamera()->setProjectionMatrixAsPerspective(45, 1, 1, 10);
view->getCamera()->setName(Stringify()<<"View "<<i);
}
MapNodeHelper().configureView(view);
viewers.addView(view);
}
if (sharedGC)
{
for(int i=1; i<numViews; ++i)
{
// 获取到第i个视景器
osgViewer::View* view = viewers.getView(i);
// 将第i个视景器,设置到多视景器的图形设备上下文中
view->getCamera()->setGraphicsContext(viewers.getView(0)->getCamera()->getGraphicsContext());
}
}
return viewers.run();
}