那我们回到ViewerBase::frame函数中来,继续看看为什么osg生命刚刚出生的时候会大哭,除了初始化了eventQuene和cameraManipulator之外还对那些器官进行了初始化。在这之前我们先介绍一下上一节说到的osg的肢体或者器官但是没有展开介绍的。
前言
osgGA::GUIEventAdapter,GUI事件适配器。它就是对所有平台windows linux mac平台上的鼠标、键盘、以及其他的窗口事件进行了封装,目的是使接口统一,用户在使用osg库的时候不用再自己区分平台,直接调用GUIEventAdapter就可以得到平台发过来的事件信息。特别是我们处理自定义的EventHandler事件处理器的时候重写handler (const osgGA::GUIActionAdapter &ea ,osgGA::GUIActionAdapter &aa)的时候一定会用到。
osgGA::GUIActionAdapter,这个内脏器官的用处比较多。我们慢慢的说。作用:定义GUIEventHandlers可以请求使用GUI操作系统的动作的抽象接口类。这些动作请求应该遵守用户所使用平台的GUI工具包的规范。例如当一个GUIEventHandler处理一个鼠标事件的时候,它希望去请求GUI,例如当一个模型被’抛出’---(使用TrackballManipulator,按住鼠标右键快速移动,然后松开右键类似抛出物体的动作)时,这个TrackballManipulator可能希望启动计时器,并重复调用,以持续刷新摄像机的位置和方向。但是,它无法做到这一点,因为它对它运行的窗口系统一无所知。得不到任何支持。相反,GUIEventHandler可以通过GUIActionAdapter发出自己的请求,然后使用这个GUI系统的viewer应该遵循这些请求。当然GUIActionAdapter的功能不只是这些,再例如我们上一节也看到了osg::Viewer::View的其中一个基类就是GUIActionAdapter,而osgViewer::View又是osgViewer::Viewer的基类,所以我们可以GUIActionAdapter强转成osgViewer::Viewer.这种使用方式一般也是在处理自定义的EventHandler事件处理器的时候重写handler (const osgGA::GUIActionAdapter &ea ,osgGA::GUIActionAdapter &aa)的时候会用到。
说了两个概念性的东西,有可能比较枯燥,但是技术类工作就是这样,每每在学习一种新的技术或者了解他背后的原理的时候,我们要耐下性子,一步一步来。只有把每一步都搞清楚弄明白我们在能继续前进不至于迷失了方向。
osgViewer::Viewer::isRealized()
我们再此回到我们的解剖课中继续探究osg类物种,osgViewer::ViewerBase::frame()中的下一步就是判读viewer是否已经被实现了,如果没有那么就要实现这个viewer。所以我们要到osgViewer::Viewer::isRealized()函数。主要功能就是这个从这个viewer中得到渲染的上下文,并且判断他们是否被实现。渲染上下文我们应该都很了解,如果您用过qt+osg一定会有这么一个过程,创建一个camera的过程需要指定操作系统的窗口属性,这个渲染的上下文就在这里指定。那我们就去osgViewer::Viewer::getContexts()下看看怎么来得到所有的GraphicsContext()。
getcontexts
osgViewer::Viewer::getContexts()。我们还是老规矩,看看这个新的动作中涉及到那些新的内脏,osg::GraphicsContext。就是图形设备对应的载体,或者说GraphicsContext是任意图形子系统的抽象接口,它提供了统一的图形设备处理函数,用来实现渲染结果和底层设备的交互。图形设备对象的主要工作是提供场景渲染结果的载体,这个载体可以显示缓存,进而绘制到一个图像窗口中,也可以是其他特殊的缓存对象,从而实现复杂的渲染和图像多次曝光等功能,创建一个图像设备不能简单地使用new运算符,因为GraphicContext类是一个不能被实例化的抽象类(这个体现在valid()等一大批纯虚函数上);通常应当使用createContext()静态函数,自动根据当前的用户环境和特性参数traits,构建一个平台相关的图形设备对象。然后绑定到摄相应的像机上。
osg::ref_ptr gc = osg::GraphicsContext::creteGraphicsContext(traits)
camera-> setGraphicContext(gc);
所以在osgViewer::Viewer::getContexts()中通过_camera->getGraphicsContext()来得到图形设备对象。
osgViewer::Viewer::getContexts()。我们又遇到了新的不认识的小零件,osg::Slave代表了主相机下的一个跟随相机,以及视图矩阵。我们在前面已经介绍过了osg::View中定义了所有的相机,当场景中只有一个主相机时,那么它即是主导也是场景的渲染器,但是有了从相机,那么主相机将视图控制到场景,而从属相机负责实现场景的渲染。所以osg::Slave中也会包含osg::GraphicsContext,也要中所有的从相机getSlaves()中得到所有的GraphicsContext。并判断他们是否可用GraphicsContexts->vaild()。这样就介绍完了viewer->getContexts().
回到Viewer::isRealized()函数中,再往下就是确定这些得到的所有的图形设备是否已经初始化完成准备被使用。
Osg::GraphicsContext::isRealized() const { return isRealizedImplementation();};
也就继承自Osg::GraphicsContext的类或者说Osg::GraphicsContext封装的底层的设备接口类中,这些类一般都在osg::Viewer::api下定义。这些类的仔细介绍我们会稍后进行讲解。这样我们就完成了ViewerBase::frame()一呼一吸动作中的第二个拆解动作isReallized()介绍。
欢迎大家来我的新家看一看 http://www.3wwang.cn