当前位置 osgViewer/View.cpp 第466行 osgViewer::View::setUpViewInWindow()
void View::setUpViewInWindow(int x, int y, int width, int height, unsigned int screenNum)
{
apply(new osgViewer::SingleWindow(x, y, width, height, screenNum));
}
五个参数,窗口左上角坐标 x,y ;窗口的宽度 width, height; 屏幕数量 screenNum.
根据给定窗口参数来创建图形设备。
接着来看看这个apply函数做了什么。
当前位置 osgViewer/View.cpp 第451行 osgViewer::View::apply()
void View::apply(ViewConfig* config)
{
if (config)
{
OSG_INFO<<"Applying osgViewer::ViewConfig : "<<config->className()<<std::endl;
config->configure(*this);
}
_lastAppliedViewConfig = config;
}
Base class for View configurations for setting up Camera and Windowing.
ViewConfig是设置相机和窗口的View配置的基类。
这里主要是看config->configure(*this)
没有找到configure函数相关的具体实现内容。关于setUpViewInWindow函数解读似乎就走到了这里,已经和锐神的不一样了。
全文件搜索configure(之后,找到了setUpViewInWindow的具体实现内容。
当前位置:osgViewer/SingleWindow.cpp 第30行
void SingleWindow::configure(osgViewer::View& view) const
osg::GraphicsContext::WindowingSystemInterface* wsi
获取WindowingSystemInterface的指针。/** Callback to be implemented to provide access to Windowing API's ability to create Windows/pbuffers.*/
如果wsi为空,则无法创建窗口。
尝试获取osg::DisplaySettings的指针。也就是获取一些viewer所需的display settings.
这个类在OSG的窗口显示中扮演了重要的地位,它保存了OSG目前用到的与图形显示有关,特别是立体显示有关的所有信息。
/** DisplaySettings class for encapsulating what visuals are required and have been set up, and the status of stereo viewing.*/
获取系统显示设置之后就要开始创建新的GraphicsContext设备了。
1、新建显示设备特性实例
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits(ds);
并设置图形窗口特性的属性值。
2、创建新的GraphicsContext设备,并将其设置给视景器的主相机。
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
view.getCamera()->setGraphicsContext(gc.get());
千万不要简单地使用 new 来创建新的 GraphicsContext 指针。
接着看剩下的工作。
从gc获取GraphicsWindow
osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(gc.get());
判断是否成功建立了gw。接着通过事件队列,调用osgGA::GUIEventAdapter::setWindowRectangle方法来记录新建立的窗口设备的大小,从而使得这个设备上所产生的事件,例如鼠标键盘事件能够以此为依据。大概是我们通过ea.getWindowX()等函数获取的跟窗口大小有关的函数,就是这样子得到的吧。
gw->getEventQueue()->getCurrentEventState()->setWindowRectangle(traits->x, traits->y, traits->width, traits->height );
接着设置主相机的透视投影参数,设置新的视口。
执行 osg::Camera::setDrawBuffer 和执行 osg::Camera:: setReadBuffer 函数,这实质上相当于在渲染的过程中执行 glDrawBuffer 和 glReadBuffer,从而自动设置此摄像机想要绘制和读取的缓存。