Cover王锐大大——最长的一帧(第二日)

第一天我们走到了ViewerBase::frame()的viewerInit()这一步,第二天就继续来看看realize()这里做了什么工作。

当前位置:osgViewer/ViewerBase.h

/** set up windows and associated threads.*/
        virtual void realize() = 0;
又是一个纯虚函数,继续到Viewer里面去找。

当然位置:osgViewer/Viewer.cpp 第473行 osgViewer::Viewer::realize()

realize(),完成窗口和场景的“设置”工作。这里是OSG会自动调用它,因为我对这个函数一点都不熟悉。这个realize()函数不简单的,接近两百行的代码一定完成了很多很多的“设置”工作。

这里王锐大大提到的setCameraWithFocus(0)现在这个版本的OSG已经没有文中的setCameraWithFocus(0)了。所以先忽略掉吧。

 Contexts contexts;
 getContexts(contexts);
这里的Contexts是一个vector<osg::GraphicsContext*>的别名。typedef std::vector<osg::GraphicsContext*> Contexts;

GraphicsContext是图形设备类定义场景渲染所处的设备平台,它可以是一个图形窗口,也可以是一个离屏渲染设备。

contexts变量保存了osg::GraphicsContext指针的向量组,Viewer::getContexts函数的作用是获取所有的图形上下文,这里我不太理解什么是图形上下文,英文就是GraphicsContext,并保存到这个向量组中。

如果要将OSG嵌入到GUI系统中(MFC.QT等)都需要和osg::GraphicsContext打交道。文中讲到了一种常用的嵌入方法,表示还看不懂,只需记住如果要用OSG嵌入Qt,这个类会起到作用。

过程是这样的:

a.设置嵌入窗口的特性(Traits),例如X,Y位置,宽度和高度,以及父窗口的句柄

b.然后根据特性的设置创建一个新的图形设备上下文(GraphicsContext),将其赋予场景所用的摄像机。

当然位置:osgViewer/Viewer.cpp 第1291行 osgViewer::Viewer::getContexts(Contexts& contexts, bool onlyValid)

typedef std::set<osg::GraphicsContext*> ContextSet;
ContextSet contextSet;
contexts.clear();
ContextSet是std::set<osg::GraphicsContext*>的别名,是一个保存图形上下文的关联容器。set是关键字即值,只保存关键字的容器。 vector::clear()方法清掉了向量组中的元素。

接着作三个判断,(1)是否有合法的主相机_camera,(2)主相机是否包含一个GraphicsContext(3)且这个图形设备有效

 contextSet.insert(_camera->getGraphicsContext());
 contexts.push_back(_camera->getGraphicsContext());
如果满足上面三个条件,则将主相机获取的GraphicsContext保存进来,插入到contextSet中,添加到contexts中。

接着遍历所有的从相机_slaves(一个视景器可以包含一个主相机,多个从相机),同样的判断从相机是否包含有效的GraphicsContext设备。再类似上面的方法保存所有找到的图形上下文设备。

这里没有看到王锐大大说的使用std::sort来进行排序工作的代码。或许是改版了。

这里需要看一下osgcamera这个例子。明天的时候来看。

继续回到realize()

当然位置:osgViewer/Viewer.cpp 第473行 osgViewer::Viewer::realize()

接下来的一段文字感觉更加不理解了。继续啃吧。这里对图形上下文这个概念真的不是很清楚,这里就暂且理解为绘制图形所需的一些设置参数内容之类的吧。

当程序还没有进入仿真循环,且没有对osgViewer::Viewer进行任何操作,系统是不会存在任何图形上下文的,即使创建一个新的osg::Camera对象,也不会为其自动分配图形上下文。但是,图形上下文GraphicsContext却是场景显示的唯一平台,系统有必要在开始渲染之前完成其创建工作。

—————————————我是分割线,以下是自己结合代码和锐神的说明整理的————————————————————

realize()函数之后的工作应该就是系统尝试创造一个缺省的GraphicsContext设备的工作了。

if (contexts.empty())
这里判断了在进入仿真循环前,用户是否自行创建了新的Camera相机对象,并为其分配了自定义的GraphicsContext设备,并将Camera对象传递给了视景器。这里需要看的例子osgViewerMFC,osgCamera。通常编写与GUI系统嵌和的仿真循环就会这么做,就是前面提到的将OSG嵌入Qt之类的,这些操作应该是在进入仿真循环前的。这个时候,系统已经不需要为图形上下文的创建做更多工作了,就不用进入下面建立缺省GraphicsContext的工作了。此时contexts应该是非空的。

OSG_INFO<<"Viewer::realize() - No valid contexts found, setting up view across all screens."<<std::endl;
// no windows are already set up so set up a default view
接着给出了注释和提示信息,没有找到合法的GraphicsContext,需要设置up view across 全屏渲染。没有已经建立好的窗口,所以建立默认的吧。
下面就是一系列的创建缺省GraphicsContext设备的代码,就不贴出来了。这里锐神给了总结。《最长的一帧》P5

在尝试创建缺省图形上下文设备后,(我为什么一会儿中文一会儿英文),再次执行getContexts,并再次判断,如果还是没有得到任何图形上下文的话,就只有退出程序了。

   if (contexts.empty())
    {
        OSG_NOTICE<<"Viewer::realize() - failed to set up any windows"<<std::endl;
        _done = true;
        return;
    }
TODO:osgCamera, osg+QT


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值