|
本帖最后由 hunter_wwq 于 2013-7-18 10:15 编辑
在盖二楼之前还有点东西原来没有补充上来,现在将这部分不上来。
猜想:所有的消息的起源都来自osgViewer::View,所以,先分析下osgViewer::View是如何将事件处理器或回调机制器加载进来的。
此类中的方法:addEventHandler(osgGA::GUIEventHandler * eventHandler);
类View中有一个属性_eventHandlers,其定义如下所示:
{{{
typedef std::list<osg::ref_ptr<osgGA::GUIEventHandler>> EventHandlers;
EventHandlers _eventHandlers;
}}}
#Q: 既然类View可以添加多个事件处理器,那么在事件发生时是如何选择事件处理器的?
类关系图如下所示:
> OsgGA::GUIEventHandler主要提供了窗口系统的GUI事件接口。它使用osgGA::GUIEventAdapter来接受更新,使用osgGA::GUIActionAdapter来向系统提出请求。
适配器osgGA::GUIActionAdapter已为基类,此类的作用是向系统提出请求,#Q: 具体是如何提出请求的呢?
#A:
osgGA::GUIAdctionAdapter完全是一个抽象基类,只声明了几个抽象方法。主要有以下几个请求:requestRedraw,requestContinuosUpdate,requestWrapPointer。
不论是osgViewer::GraphicsWindow还是osgViewer::View在实现这三类方法时都是直接或间接的去设置osgViewer::ViewerBase的标志位:_requestRedraw,_requestContinusUpdate;而requestWrapPointer都是间接地去调用osgViewer::GraphicsWindow中的继承方法。
#Q: 相机在这中间期到了一个什么作用?相机既能获取osgViewer::View又能获取osgViewer::GraphicsWindow。osg::View用来管理所有的相机视图。。
#Q: 适配器osgGA::GUIEventAdapter如何获取更新?
#A: osgGA::GUIEventAdapter只定义了各类消息和事件的枚举类型,以及设置和获取消息和事件值(set/get)。具体设置消息和事件值得地方在osgGA::EventQueue中。所以消息的更进一个源头是在osgGA::EventQueue中产生。
#Q: osgGA::EventQueue是如何接收消息的?
#A:
osgGA::EventQueue继承关系图
而调用osgGA::EventQueue中具体某类消息的源头是在:osgViewer::GraphicsWindowWin32中的方法:
{{{
virtual LRESULT handleNativeWindowingEvent(HWND hwnd, UINT uMsg, WPARAM wParam , LPARAM lParam);
}}}
而最终handleNativeWindowingEvent方法调用的源头在文件GraphicsWindowWin32.cpp中的窗口过程函数static LRESULT CALLBACK WindowProc中:
- static LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- osgViewer::GraphicsWindowWin32* window = Win32WindowingSystem::getInterface()->getGraphicsWindowFor(hwnd);
- return window ? window->handleNativeWindowingEvent(hwnd, uMsg, wParam, lParam) :
- ::DefWindowProc(hwnd, uMsg, wParam, lParam);
- }
复制代码 #Q: 有关窗口类、窗口、及窗口过程的注册如何进行的?
#A: 在源文件GraphicsWindowWin32.cpp文件中声明并定义的类:
- class Win32WindowSystem : public osg::GraphicsContext::WindowSystemInterface
复制代码 该类提供了注册窗口、注册窗口类的方法。通过将HWND和osgViewer::GraphicsWindowWin32关联起来。
窗口的创建是在osgViewer::GraphicsWindowWin32::createWindow中进行的。
而这些工作全都在osgViewer::GraphicsWindowWin32::init方法中进行,方法init在该类的构造函数中进行调用。
最终的方法还是在Win32WindowSystem::createGraphicsContext中进行的。
可参照项目Review中对GraphicsWindow的初始化代码:在RenderModule.cpp文件中方法initViewer中:
- HWND hWnd = context.uc().mainframe()->m_wndView->m_hWnd;
- RECT rect;
- ::GetClientRect(hWnd, &rect);
- osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
- osg::ref_ptr<osgViewer::GraphicsWindowWin32::WindowData> windata = new osgViewer::GraphicsWindowWin32::WindowData(hWnd);
- traits->x = 0;
- traits->y = 0;
- traits->width = rect.right - rect.left;
- traits->height = rect.bottom - rect.top;
- traits->windowDecoration = false;
- traits->doubleBuffer = true;
- traits->sharedContext = 0;
- traits->setInheritedWindowPixelFormat = true;
- traits->inheritedWindowData = windata;
- if (context.ac().antialiasing)
- {
- traits->sampleBuffers = true;
- traits->samples = 4;
- }
- osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
复制代码 |
|