原文地址:http://blog.csdn.net/sunxiaoju/article/details/50225647
1、首先定义一个类,该类继承与osgGA::GUIEventHandler,在此类中存在一个handle函数,所有的事件都在此函数中进行处理,如下类的代码:
- //声明类UseEventHandler,由于它是从osgGA::GUIEventHandler派生而来,所以它拥有处理事件的能力,其中这种能力体现在一个虚函数handle上。
- //一切的处理都在handle当中。
- class UseEventHandler:public::osgGA::GUIEventHandler
- {
- public:
- //handle函数,其中有两个极其重要的参数,
- //一个是const osgGA::GUIEventAdapter,注意有不少人在写时少写了个const结果就不灵了,
- //因为是虚函数,参数必须与父类中虚函数相应一致。该参数是用来识别各种事件类型的参数。
- //第二个参数也很重要:osgGA::GUIActionAdapter,它是控制显示的参数,其实最重要的是它是Viewer的祖父类,由它可以得到viewer,在操作中有体现。
- virtual bool handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &aa)
- {
- //将aa强制转换为viewer对象
- osgViewer::Viewer *viewer=dynamic_cast<osgViewer::Viewer*>(&aa);
- if (!viewer)//如果转换失败则直接退出
- {
- return false;
- }
- switch(ea.getEventType())//获取事件的类型,是键盘上的事件,还是鼠标上的事件以及鼠标单击,右击,双击等等。
- {
- case osgGA::GUIEventAdapter::KEYDOWN://键盘响应事件
- if (ea.getKey()==0xFF51)
- {
- //首先获得场景中的数据,然后在获得Group,然后在获得Group的子节点,最后设置显示模式
- viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(1);//按向左的方向键
- viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(0);
- }
- if (ea.getKey()==0xFF53)
- {
- viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(0);//按下向右的方向键
- viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(1);
- }
- break;
- case osgGA::GUIEventAdapter::PUSH:
- if (ea.getButton()==4)//表示按鼠标右键
- {
- viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(0);
- viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(0);
- }
- break;
- case osgGA::GUIEventAdapter::DOUBLECLICK://表示双击类型
- if (ea.getButton()==1)//表示按鼠标左键
- {
- viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(1);
- viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(1);
- }
- break;
- default:
- break;
- }
- return false;
- }
- };
2、写完了类,然后就是在场景中通过viewer.addEventHandler(new UseEventHandler());为场景添加定义好的事件类,如下代码所示:
- //将UseEventHandler加入到viewer事件中,在UseEventHandler会有一个handle函数,此函数有两个参数,第一个参数是捕捉事件的,比如鼠标单击,双击,键盘事件等等
- //第二个参数则是viewer的祖父GUIActionAdapter,可以通过强制转换来获得viewer对象,这样就可以在事件中控制场景中的物体模型了
- viewer.addEventHandler(new UseEventHandler());
3、完整的代码如下:
- #include "stdafx.h"
- #include <osgDB/ReadFile>
- #include <osgViewer/Viewer>
- #include <osg/Node>
- //声明类UseEventHandler,由于它是从osgGA::GUIEventHandler派生而来,所以它拥有处理事件的能力,其中这种能力体现在一个虚函数handle上。
- //一切的处理都在handle当中。
- class UseEventHandler:public::osgGA::GUIEventHandler
- {
- public:
- //handle函数,其中有两个极其重要的参数,
- //一个是const osgGA::GUIEventAdapter,注意有不少人在写时少写了个const结果就不灵了,
- //因为是虚函数,参数必须与父类中虚函数相应一致。该参数是用来识别各种事件类型的参数。
- //第二个参数也很重要:osgGA::GUIActionAdapter,它是控制显示的参数,其实最重要的是它是Viewer的祖父类,由它可以得到viewer,在操作中有体现。
- virtual bool handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &aa)
- {
- //将aa强制转换为viewer对象
- osgViewer::Viewer *viewer=dynamic_cast<osgViewer::Viewer*>(&aa);
- if (!viewer)//如果转换失败则直接退出
- {
- return false;
- }
- switch(ea.getEventType())//获取事件的类型,是键盘上的事件,还是鼠标上的事件以及鼠标单击,右击,双击等等。
- {
- case osgGA::GUIEventAdapter::KEYDOWN://键盘响应事件
- if (ea.getKey()==0xFF51)
- {
- //首先获得场景中的数据,然后在获得Group,然后在获得Group的子节点,最后设置显示模式
- viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(1);//按向左的方向键
- viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(0);
- }
- if (ea.getKey()==0xFF53)
- {
- viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(0);//按下向右的方向键
- viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(1);
- }
- break;
- case osgGA::GUIEventAdapter::PUSH:
- if (ea.getButton()==4)//表示按鼠标右键
- {
- viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(0);
- viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(0);
- }
- break;
- case osgGA::GUIEventAdapter::DOUBLECLICK://表示双击类型
- if (ea.getButton()==1)//表示按鼠标左键
- {
- viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(1);
- viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(1);
- }
- break;
- default:
- break;
- }
- return false;
- }
- };
- int _tmain(int argc, _TCHAR* argv[])
- {
- osgViewer::Viewer viewer;
- osg::ref_ptr<osg::Group> root=new osg::Group();
- root->addChild(osgDB::readNodeFile("avatar.osg"));
- root->addChild(osgDB::readNodeFile("glider.osg"));
- viewer.setSceneData(root.get());
- //将UseEventHandler加入到viewer事件中,在UseEventHandler会有一个handle函数,此函数有两个参数,第一个参数是捕捉事件的,比如鼠标单击,双击,键盘事件等等
- //第二个参数则是viewer的祖父GUIActionAdapter,可以通过强制转换来获得viewer对象,这样就可以在事件中控制场景中的物体模型了
- viewer.addEventHandler(new UseEventHandler());
- viewer.realize();
- return viewer.run();
- }
4、ea.getEventType()可获取的类型包括以下内容:
| 代码 | 值 | 事件类型 |
| NONE | 0 | 无事件。 |
| PUSH | 1 | 鼠标某键按下 |
| RELEASE | 2 | 鼠标某键弹起。 |
| DOUBLECLICK | 4 | 鼠标某键双击。 |
| DRAG | 8 | 鼠标某键拖动。 |
| MOVE | 16 | 鼠标移动。 |
| KEYDOWN | 32 | 键盘上某键按下。 |
| KEYUP | 64 | 键盘上某键弹起。 |
| FRAME | 128 | 应该是鼠标每帧。没用过。 |
| RESIZE | 256 | 窗口大小改变时会有的事件。 |
| SCROLL | 512 | 鼠标轮滚动。 |
| PEN_PRESSURE | 1024 | 手写板的某事件? |
| PEN_PROXIMITY_ENTER | 2048 | 手写板的某事件? |
| PEN_PROXIMITY_LEAVE | 4096 | 手写板的某事件? |
| CLOSE_WINDOWS | 8192 | 关闭窗口。 |
| QUIT_APPLICATION | 16384 | 退出程序。 |
| USER | 32768 | 用户定义。 |
5、osg中支持的键盘编码值列表如下:
| 键 | 值 | 键 | 值 |
| KEY_Space | 0x20 | KEY_KP_Tab | 0xFF89 |
| KEY_BackSpace | 0xFF08 | KEY_KP_Enter | 0xFF8D |
| KEY_Tab | 0xFF09 | KEY_KP_F1 | 0xFF91 |
| KEY_Linefeed | 0xFF0A | KEY_KP_F2 | 0xFF92 |
| KEY_Clear | 0xFF0B | KEY_KP_F3 | 0xFF93 |
| KEY_Return | 0xFF0D | KEY_KP_F4 | 0xFF94 |
| KEY_Pause | 0xFF13 | KEY_KP_Home | 0xFF95 |
| KEY_Scroll_Lock | 0xFF14 | KEY_KP_Left | 0xFF96 |
| KEY_Sys_Req | 0xFF15 | KEY_KP_Up | 0xFF97 |
| KEY_Escape | 0xFF1B | KEY_KP_Right | 0xFF98 |
| KEY_Delete | 0xFFFF | KEY_KP_Down | 0xFF99 |
| KEY_Home | 0xFF50 | KEY_KP_Prior | 0xFF9A |
| KEY_Left | 0xFF51 | KEY_KP_Page_Up | 0xFF9A |
| KEY_Up | 0xFF52 | KEY_KP_Next | 0xFF9B |
| KEY_Right | 0xFF53 | KEY_KP_Page_Down | 0xFF9B |
| KEY_Down | 0xFF54 | KEY_KP_End | 0xFF9C |
| KEY_Prior | 0xFF55 | KEY_KP_Begin | 0xFF9D |
| KEY_Page_Up | 0xFF55 | KEY_KP_Insert | 0xFF9E |
| KEY_Next | 0xFF56 | KEY_KP_Delete | 0xFF9F |
| KEY_Page_Down | 0xFF56 | KEY_KP_Equal | 0xFFBD |
| KEY_End | 0xFF57 | KEY_KP_Multiply | 0xFFAA |
| KEY_Begin | 0xFF58 | KEY_KP_Add | 0xFFAB |
| KEY_Select | 0xFF60 | KEY_KP_Separator | 0xFFAC |
| KEY_Print | 0xFF61 | KEY_KP_Subtract | 0xFFAD |
| KEY_Execute | 0xFF62 | KEY_KP_Decimal | 0xFFAE |
| KEY_Insert | 0xFF63 | KEY_KP_Divide | 0xFFAF |
| KEY_Undo | 0xFF65 | ||
| KEY_Redo | 0xFF66 | KEY_KP_0 | 0xFFB0 |
| KEY_Menu | 0xFF67 | KEY_KP_1 | 0xFFB1 |
| KEY_Find | 0xFF68 | KEY_KP_2 | 0xFFB2 |
| KEY_Cancel | 0xFF69 | KEY_KP_3 | 0xFFB3 |
| KEY_Help | 0xFF6A | KEY_KP_4 | 0xFFB4 |
| KEY_Break | 0xFF6B | KEY_KP_5 | 0xFFB5 |
| KEY_Mode_switch | 0xFF7E | KEY_KP_6 | 0xFFB6 |
| KEY_Script_switch | 0xFF7E | KEY_KP_7 | 0xFFB7 |
| KEY_Num_Lock | 0xFF7F | KEY_KP_8 | 0xFFB8 |
| KEY_KP_Space | 0xFF80 | KEY_KP_9 | 0xFFB9 |
| KEY_F1 | 0xFFBE | KEY_F24 | 0xFFD5 |
| KEY_F2 | 0xFFBF | KEY_F25 | 0xFFD6 |
| KEY_F3 | 0xFFC0 | KEY_F26 | 0xFFD7 |
| KEY_F4 | 0xFFC1 | KEY_F27 | 0xFFD8 |
| KEY_F5 | 0xFFC2 | KEY_F28 | 0xFFD9 |
| KEY_F6 | 0xFFC3 | KEY_F29 | 0xFFDA |
| KEY_F7 | 0xFFC4 | KEY_F30 | 0xFFDB |
| KEY_F8 | 0xFFC5 | KEY_F31 | 0xFFDC |
| KEY_F9 | 0xFFC6 | KEY_F32 | 0xFFDD |
| KEY_F10 | 0xFFC7 | KEY_F33 | 0xFFDE |
| KEY_F11 | 0xFFC8 | KEY_F34 | 0xFFDF |
| KEY_F12 | 0xFFC9 | KEY_F35 | 0xFFE0 |
| KEY_F13 | 0xFFCA | KEY_Shift_L | 0xFFE1 |
| KEY_F14 | 0xFFCB | KEY_Shift_R | 0xFFE2 |
| KEY_F15 | 0xFFCC | KEY_Control_L | 0xFFE3 |
| KEY_F16 | 0xFFCD | KEY_Control_R | 0xFFE4 |
| KEY_F17 | 0xFFCE | KEY_Caps_Lock | 0xFFE5 |
| KEY_F18 | 0xFFCF | KEY_Shift_Lock | 0xFFE6 |
| KEY_F19 | 0xFFD0 | ||
| KEY_F20 | 0xFFD1 | KEY_Meta_L | 0xFFE7 |
| KEY_F21 | 0xFFD2 | KEY_Meta_R | 0xFFE8 |
| KEY_F22 | 0xFFD3 | KEY_Alt_L | 0xFFE9 |
| KEY_F23 | 0xFFD4 | KEY_Alt_R | 0xFFEA |
| KEY_Super_L | 0xFFEB | KEY_Hyper_L | 0xFFED |
| KEY_Super_R | 0xFFEC | KEY_Hyper_R | 0xFFEE |
浙公网安备 33010602011771号