osgViewer::Viewer詳解
l 構造函數Viewer::Viewer(osg::ArgumentParser& arguments)可以做一些初始化工作,比如當讀取參數--clear-color時,可以設置背景顏色。詳細請參考源碼。建議不使用。
l 函數setThreadingModel設置線程模型
SingleThreaded - 單CPU,單顯示器時使用;
DrawThreadPerContext - 多CPU,單顯示器時使用,以增加幀延遲時間爲代價,提高屏幕同步刷新率;
CullThreadPerCameraDrawThreadPerContext - 攝像機和顯示器的總數不大於CPU數;
CullDrawThreadPerContext - 上述情況之外,可以保證較低的幀延遲時間。
在DrawThreadPerContext和CullThreadPerCameraDrawThreadPerContext模式下,渲染遍歷renderingTraversals()可能在繪製線程完成之前就會返回,此時如果用戶修改STATIC類型的節點,幾何體和渲染狀態數據,就可能發生危險,必須使用setDataVariance(DYNAMIC)來指定數據類型。
用戶可以在程序中隨時使用osgViewer::Viewer::setThreadingModel函數來設置任意一個線程模型,不必拘泥於上面所述的限制。
l 單窗口多攝像機的實現
一)得到屏幕分辨率(此方法也可以得到和改變屏幕分辨率)
osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
if (!wsi)
{
osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
return;
}
unsigned int width, height;
wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
二)設置設備上下文
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->x = 0;
traits->y = 0;
traits->width = width;
traits->height = height;
traits->windowDecoration = true;
traits->doubleBuffer = true;
traits->sharedContext = 0;
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
三)清空整個屏幕的顏色,注意:它和Viewer的setClearColor區別是設置整個屏幕還是所在視口的顏色
setClearMask參數:(默認GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
GL_ACCUM_BUFFER_BIT // 累積緩衝
GL_COLOR_BUFFER_BIT // 顏色緩衝
GL_DEPTH_BUFFER_BIT // 深度緩衝
GL_STENCIL_BUFFER_BIT)// 模板緩衝
if (gc.valid())
{
osg::notify(osg::INFO)<<" GraphicsWindow has been created successfully."<<std::endl;
//使整個屏幕的顏色被清除,而不是僅僅改變一個視口
//以後每次調用setClearMask顏色都會被清除爲指定顏色,除非又調用了setClearColor設置不同的顏色
gc->setClearColor(osg::Vec4f(0.2f,0.2f,0.6f,1.0f));
gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
else
{
osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."<<std::endl;
}
四)爲每個攝像機設置設備上下文與緩衝
說明:使用雙緩衝,每一幀只在繪圖完成後才被顯示,不會顯示不完整的幀
//攝像機個數
unsigned int numCameras = 2;
double aspectRatioScale = 1.0;///(double)numCameras;
for(unsigned int i=0; i<numCameras;++i)
{
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setGraphicsContext(gc.get());
camera->setViewport(new osg::Viewport((i*width)/numCameras,(i*height)/numCameras, width/numCameras, height/numCameras));
GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
//設置繪製緩衝,它在每幀繪製之前使用。注意:如果參數書GL_NONE,
//則在每幀繪製後自動加載合適的參數
camera->setDrawBuffer(buffer);
//爲拷貝操作設置讀緩衝
camera->setReadBuffer(buffer);
viewer.addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::scale(aspectRatioScale,1.0,1.0));
}
關於addSlave函數
三個參數分別是:攝像機地址,投影偏移矩陣,視圖偏移矩陣
待續……