【OSG原理与源码分析】OSG事件处理模块 概念 原理与源码分析 (Windows版) OSG事件处理模块源码可能的困惑答疑 调查研究调试OSG框架源码之后才创作的博客

简介

本文将介绍三维渲染引擎开源框架OSG(Open Scene Graph)的事件处理模块的Windows版的原理与源码分析。本文将介绍OSG事件适配器、OSG事件执行者、OSG事件处理器等技术概念和具体C++类型。本文还将介绍OSG事件处理模块Windows版的实现思路。本文最后还将介绍OSG事件处理模块的源码分析。本文还将对OSG事件处理模块源码阅读过程中可能产生的困惑进行答疑解惑。这篇OSG框架技术博客是调查研究调试OSG框架源码之后才创作的博客,如果对读者朋友们有一些帮助,则倍感欣慰。

正文

OSG事件处理模块的技术概念和数据类型

OSG事件(Event)

OSG框架中的事件,表示某个具体的操作系统事件或者框架自定义事件。OSG事件的祖宗类型是Event类型。从类型定义看,Event类型也是一个OSG对象类型(Object)。

class OSGGA_EXPORT Event : public osg::Object
{
   
public:
    Event();
    Event(const Event& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);

	//稍后解释META_Object是什么。
	//大型C++开源框架都喜欢玩这种宏定义的套路
    META_Object(osgGA, Event);

	//重新实现了asGuiEventAdapater()函数
	//表示一个事件对象默认不是一个事件适配器对象;
	//但是OSG中有一些事件适配器类型确实是事件类型的派生类。
    virtual GUIEventAdapter* asGUIEventAdapter() {
    return 0; }
    virtual const GUIEventAdapter* asGUIEventAdapter() const {
    return 0; }

	//设置/获取当前事件对象表示的事件是否已经被处理过了
    //具体是什么时间,稍后会介绍。
    void setHandled(bool handled) const {
    _handled = handled; }
    bool getHandled() const {
    return _handled; }

	//设置/获取事件的时间
    void setTime(double time) {
    _time = time; }
    double getTime() const {
    return _time; }

protected:
	//事件对象不能在对象外部进行销毁
    virtual ~Event() {
   }
    mutable bool        _handled;
    double              _time;
};


META_Object()宏定义的定义如下所示,定义了一系列的“元函数”,简化了具体事件类型的实现。

```cpp
#define META_Object(library,name) \
        virtual osg::Object* cloneType() const {
      return new name (); } \
        virtual osg::Object* clone(const osg::CopyOp& copyop) const {
      return new name (*this,copyop); } \
        virtual bool isSameKindAs(const osg::Object* obj) const {
      return dynamic_cast<const name *>(obj)!=NULL; } \
        virtual const char* libraryName() const {
      return #library; }\
        virtual const char* className() const {
      return #name; }

然后来讨论时间中包含的时间。在一个事件加入到OSG框架的事件队列时,事件会被设置为加入队列时所在时刻的时间。当一个事件从OSG框架事件队列取出来时,该事件的时间会被设置为取出时所在时刻的时间。

OSG事件适配器(EventAdapater)

OSG框架中的事件适配器,是用于表示各种事件类型。通常操作系统中支持的事件类型特别多,比如仅仅鼠标左键相关事件就有按下、松开、移动、单击、双击等具体事件类型。作为OSG框架,如何使用具体的C++类型来表达这些不同的事件呢?

这有两种思路。
OSG框架的思路:
将所有图形用户界面有关的事件综合到一个数据类型中,也就是GUI事件适配器GUIEventAdapter类型。GUIEventAdapter这个类型是从Event类型派生而来的。结果就是一个C++数据类型必须能够同时表达所有的GUI事件。

QT框架的思路:
为每一个事件设计一个具体的C++类型。结果就是设计出了太多的C++数据类型。

在这里不打算去评判哪一种设计思路更好,仅仅列出来供读者朋友们拓展复杂软件框架的设计思路。


class OSGGA_EXPORT GUIEventAdapter : public Event
{
   
public:
     GUIEventAdapter();
     GUIEventAdapter(const GUIEventAdapter& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);

        META_Object(osgGA, GUIEventAdapter);

		//这种GUI事件适配器类型本身就是一个GUIEventAdapter类型,
		//显然可以直接转换为GUIEventAdapter类型
        virtual GUIEventAdapter* asGUIEventAdapter() {
    return this; }
        virtual const GUIEventAdapter* asGUIEventAdapter() const {
    return this; }

	    //获取累积的事件状态对象的指针
        static osg::ref_ptr<GUIEventAdapter>& getAccumulatedEventState();

		//设置/获取事件类型
		//这样就可以识别不同的具体事件
        void setEventType(EventType Type) {
    _eventType = Type; }
        virtual EventType getEventType() const {
    return _eventType; }
        
        //设置/获取图形上下文
        void setGraphicsContext(osg::GraphicsContext* context) {
    _context = context; }
        osg::GraphicsContext* getGraphicsContext() {
    return _context.get(); }
        const osg::GraphicsContext* getGraphicsContext() const {
    return _context.get(); }
       
       //键盘事件
        inline void setKey(int key) {
    _key = key; }
        virtual int getKey() const {
    return _key; }
        void setUnmodifiedKey(int key) {
    _unmodifiedKey = key; }
        int getUnmodifiedKey() const {
    return _unmodifiedKey; }

	    //鼠标事件
        void setButton(int button) {
    _button = button; }
        int getButton() const {
    return _button; }
        void setX(float x) {
    _mx = x; }
        float getX() const {
    return _mx; }
        void setY(float y) {
    _my = y; }
        float getY() const {
    return _my; }

    protected:
        virtual ~GUIEventAdapter();
        EventType _eventType;
        osg::observer_ptr<osg::GraphicsContext> _context;
        
        //窗口位置和大小事件信息
        int _windowX;
        int _windowY;
        int _windowWidth;
        int _windowHeight;

		//键盘事件和鼠标事件信息	
        int _key;
        int _unmodifiedKey;
        int _button;
        float _Xmin,_Xmax;
        float _Ymin,_Ymax;
        float _mx;
        float _my;
        int _buttonMask;
        int _modKeyMask;
        MouseYOrientation _mouseYOrientation;
        Scrolling _scrolling;

		//其它一些GUI事件信息
        TabletPen _tabletPen;
        osg::ref_ptr<TouchData> _touchData;
        PointerDataList _pointerDataList;
};


OSG行为适配器(ActionAdapter)

OSG行为适配器用于在事件处理器的事件处理函数的执行过程中,对窗口界面实施某种特定的行为操作影响。


class GUIActionAdapter
{
   
public:
        virtual ~GUIActionAdapter() {
   }
        virtual osg::View* asView() {
    return 0; }

		//请求重绘一次
        virtual void requestRedraw() 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值