本文为osg源码学习笔记,有理解不当之处,请随时指正.
PS: 本文参考osg 版本: 3.4.0
1. 事件处理框架
OSG的事件处理可分为两个大的模块.
1) 事件适配模块(类图右侧) : 为各窗口平台中间抽象层(GA: GUI Abstraction)或适配层, 将各平台的用户输入事件适配为OSG内部定义的事件(EventAdapter).
2) 事件处理模块(类图左侧): 为用户提供输入事件的处理机制. 用户注册事件handler,对输入事件(EventAdapter)进行处理.
2. 源码分析
按照从 用户事件输入->用户事件处理的过程,用源码佐证上述分析. 整个分析过程,以鼠标事件为例.
1) 平台相关事件 适配为 OSG内部定义事件
a. 接收用户输入
源码现场: GraphicsWindowWin32::handleNativeWindowingEvent()
以鼠标事件为例,将windows鼠标事件的相关信息,交由eventqueue处理.
case WM_LBUTTONDOWN :
case WM_MBUTTONDOWN :
case WM_RBUTTONDOWN :
/////////////////////
{
::SetCapture(hwnd);
int button;
if (uMsg==WM_LBUTTONDOWN) button = 1;
else if (uMsg==WM_MBUTTONDOWN) button = 2;
else button = 3;
_capturedMouseButtons.insert(button);
float mx = GET_X_LPARAM(lParam);
float my = GET_Y_LPARAM(lParam);
transformMouseXY(mx, my);
getEventQueue()->mouseButtonPress(mx, my, button, eventTime);
}
break;
b. 适配事件, 并添加至事件队列
源码现场: osgGA::GUIEventAdapter* EventQueue
GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
event->setEventType(GUIEventAdapter::PUSH);
event->setTime(time);
switch(button)
{
case(1):
event->setButton(GUIEventAdapter::LEFT_MOUSE_BUTTON);
break;
case(2):
event->setButton(GUIEventAdapter::MIDDLE_MOUSE_BUTTON);
break;
case(3):
event->setButton(GUIEventAdapter::RIGHT_MOUSE_BUTTON);
break;
}
addEvent(event);2) 事件处理
至此,用户 输入外部事件已经适配为osg内部eventAdapter,并添加至事件队列中.
Viewer负责在事件更新循环中,将事件队列中的事件,分发给各event handler进行处理.
源码现场: Viewer::eventTraversal()
for(osgGA::EventQueue::Events::iterator itr = events.begin();
itr != events.end();
++itr)
{
osgGA::Event* event = itr->get();
for(EventHandlers::iterator hitr = _eventHandlers.begin();
hitr != _eventHandlers.end();
++hitr)
{
(*hitr)->handle( event, 0, _eventVisitor.get());
}
}
738

被折叠的 条评论
为什么被折叠?



