CEGUI、DirectX和OIS结合

OIS即面向对象的输入系统(Object-Oriented Input System(OIS)

OIS是一个面向对象的输入系统,理论上它可以支持任何输入设备,其中最主要的三类是键盘、鼠标和游戏控制器。OIS是一个开放源码的项目,你可以按你的要求定制它,以满足你的需求。

下载地址:http://sourceforge.net/projects/wgois/

主要过程:

1.编译好OIS

2.创建好windows窗口,初始化Directx和CEGUI

3.初始化输入管理系统和输入设备

    HWND m_hWnd;

    OIS::InputManager *m_pInputManager;

    OIS::Mouse *m_pMouse;

    OIS::Keyboard *m_pKeyboard;



    OIS::ParamList pl;

    std::ostringstream windowHndStr;

    windowHndStr <<(size_t)hwnd;     // 窗口句柄

    pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));       // 传入窗口句柄                               

    pl.insert(std::make_pair(std::string("w32_mouse"), "DISCL_FOREGROUND"));    //前台模式,也就是说使用它的程序必须处于激活状态,

                                                                        //如果它失去焦点就会自动失去设备,在它重新获得焦点的时候必须重新获得设备使用权



    pl.insert(std::make_pair(std::string("w32_mouse"), "DISCL_NONEXCLUSIVE"));  // 允许其他程序使用,并且不会干扰其他应用程序的使用



    // 创建输入设备

    m_pInputManager = OIS::InputManager::createInputSystem( pl );





    //m_pInputManager=OIS::InputManager::createInputSystem((size_t)m_hWnd);

    m_pMouse = static_cast<OIS::Mouse*>(m_pInputManager->createInputObject( OIS::OISMouse, true));//第三个参数为真是为缓冲处理

    m_pKeyboard = static_cast<OIS::Keyboard*>(m_pInputManager->createInputObject( OIS::OISKeyboard, true ));

首先我们先讲一个问题,就是 缓冲和非缓冲。

缓冲输入就是说你每次的按键值都要先存入缓冲区,等程序有时间了就会去做相应的处理,意思说只要你按了某个键,电脑早晚都会给你做相应的事情,哪怕等到程序死机(如果这样,说明你很不幸哦!)。非缓冲就是程序现在有时间处理你的时候来问你,“有什么要做的没?“,如果这是你的鼠标键盘有任何时间的话,程序就做相应的处理,没有的话,不做任何处理,哪怕在这之前你按了鼠标或者键盘的某些键,程序也会忽略。它们的区别就是缓冲可以处理一切事件,但是需要缓冲,则比较慢,非缓冲可能会忽略某些信息,但是它不需要缓冲,处理速度要快一些。

4.创建并设置监听类

class GuiFrameListener:public OIS::MouseListener,public OIS::KeyListener

{

private:

    bool mShoutdownRequested; //结束标志

    HWND m_hWnd;



public:

    GuiFrameListener(HWND hWnd)

    {

        m_hWnd=hWnd;

        mShoutdownRequested=true;

    }



    bool quit(const CEGUI::EventArgs &evt)

    {

        mShoutdownRequested=true;

        return true;

    }





    bool mouseMoved(const OIS::MouseEvent &evt);

    bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id) ;

    bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id );

    bool keyPressed(const OIS::KeyEvent &evt );

    bool keyReleased(const OIS::KeyEvent &evt );

    void doNumKeyboard(OIS::KeyEvent &evt);

};
    m_listener=new GuiFrameListener(m_hWnd);

    m_pMouse->setEventCallback(m_listener);

    m_pKeyboard->setEventCallback(m_listener);

5.在循环函数中加入输入设备的接收数据接口

        m_pMouse->capture();

        m_pKeyboard->capture();

6.OIS与CEGUI结合,主要是在监听类里的鼠标键盘响应函数中加入响应的injectXXXXX函数

例如鼠标按下的:

bool  GuiFrameListener::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id) 

{

    CEGUI::System::getSingleton().injectMouseButtonDown(convertOgreButtonToCegui(id));

    return true;

}

7.因为传入鼠标ID的时候 OIS::MouseButtonID和CEGUI::MouseButton是两个不同的枚举,所以要作下转换

CEGUI::MouseButton convertOgreButtonToCegui(int buttonID)

{

    switch (buttonID)

    {

    case OIS::MB_Left:

        return CEGUI::LeftButton;

    case OIS::MB_Right:

        return CEGUI::RightButton;

    case OIS::MB_Middle:

        return CEGUI::MiddleButton;

    default:

        return CEGUI::LeftButton;

    }

}

 

下面是完整的代码:

头文件

#ifndef _OISAPP_H_

#define  _OISAPP_H_



#include <windows.h>

#include "OIS.h"

#include"CEGUI.h"



using namespace std;



#ifdef _DEBUG



#pragma comment( lib, "OIS_d.lib" )

#else

#pragma comment( lib, "OIS.lib" )

#endif



CEGUI::MouseButton convertOgreButtonToCegui(int buttonID);



class GuiFrameListener:public OIS::MouseListener,public OIS::KeyListener

{

private:

    bool mShoutdownRequested; //结束标志

    HWND m_hWnd;



public:

    GuiFrameListener(HWND hWnd)

    {

        m_hWnd=hWnd;

        mShoutdownRequested=true;

    }



    bool quit(const CEGUI::EventArgs &evt)

    {

        mShoutdownRequested=true;

        return true;

    }





    bool mouseMoved(const OIS::MouseEvent &evt);

    bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id) ;

    bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id );

    bool keyPressed(const OIS::KeyEvent &evt );

    bool keyReleased(const OIS::KeyEvent &evt );

    void doNumKeyboard(OIS::KeyEvent &evt);

};



class OISApp

{

public:

    OISApp();

    ~OISApp();



    bool Init(HWND hwnd);

    void capture();

public:

    HWND m_hWnd;

    OIS::InputManager *m_pInputManager;

    OIS::Mouse *m_pMouse;

    OIS::Keyboard *m_pKeyboard;

    GuiFrameListener *m_listener;

    

    

};

















#endif

cpp

#include "oisApp.h"

#include "publicFunc.h"





CEGUI::MouseButton convertOgreButtonToCegui(int buttonID)

{

    switch (buttonID)

    {

    case OIS::MB_Left:

        return CEGUI::LeftButton;

    case OIS::MB_Right:

        return CEGUI::RightButton;

    case OIS::MB_Middle:

        return CEGUI::MiddleButton;

    default:

        return CEGUI::LeftButton;

    }

}

////////////

OISApp::OISApp()

{



    m_pInputManager=NULL;

    m_pMouse=NULL;

    m_pKeyboard=NULL;

    m_listener=NULL;



}



OISApp::~OISApp()

{

    m_pInputManager->destroyInputObject(m_pMouse);

    m_pInputManager->destroyInputObject(m_pKeyboard);

    OIS::InputManager::destroyInputSystem(m_pInputManager);

    safeDele(m_listener);



}



bool OISApp::Init(HWND hwnd)

{

    if(m_hWnd<=0)

    {

    printf("ERROR: m_hWnd <=0\n");

    return false;

    }

    m_hWnd=hwnd;





    OIS::ParamList pl;

    std::ostringstream windowHndStr;

    windowHndStr <<(size_t)hwnd;     // 窗口句柄

    pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));       // 传入窗口句柄                               

    pl.insert(std::make_pair(std::string("w32_mouse"), "DISCL_FOREGROUND"));    //前台模式,也就是说使用它的程序必须处于激活状态,

                                                                        //如果它失去焦点就会自动失去设备,在它重新获得焦点的时候必须重新获得设备使用权



    pl.insert(std::make_pair(std::string("w32_mouse"), "DISCL_NONEXCLUSIVE"));  // 允许其他程序使用,并且不会干扰其他应用程序的使用



    // 创建输入设备

    m_pInputManager = OIS::InputManager::createInputSystem( pl );





    //m_pInputManager=OIS::InputManager::createInputSystem((size_t)m_hWnd);

    m_pMouse = static_cast<OIS::Mouse*>(m_pInputManager->createInputObject( OIS::OISMouse, true));//第三个参数为真是为缓冲处理

    m_pKeyboard = static_cast<OIS::Keyboard*>(m_pInputManager->createInputObject( OIS::OISKeyboard, true ));



    m_listener=new GuiFrameListener(m_hWnd);

    m_pMouse->setEventCallback(m_listener);

    m_pKeyboard->setEventCallback(m_listener);



    // 设置鼠标移动范围,OIS默认范围为50*50

    RECT clientRect;

    GetClientRect(m_hWnd,&clientRect);

    //GetWindowRect(m_hWnd,&clientRect);

    m_pMouse->getMouseState().width =clientRect.right;

    m_pMouse->getMouseState().height = clientRect.bottom;



    ShowCursor(0); //隐藏系统鼠标指针



    return true;

}

void  OISApp::capture()

{

    if (m_pMouse&&m_pKeyboard)

    {

        m_pMouse->capture();

        m_pKeyboard->capture();

    }

}

///////////////////////////





bool GuiFrameListener::mouseMoved(const OIS::MouseEvent &evt)

{

    //CEGUI::System::getSingleton().injectMouseMove(evt.state.X.rel,evt.state.Y.rel);

    RECT clientRect;

    GetClientRect(m_hWnd,&clientRect);

    //GetWindowRect(m_hWnd,&clientRect);

    int width =clientRect.right;

    int height = clientRect.bottom;

    int curx=evt.state.X.abs;

    int cury=evt.state.Y.abs;

    if (curx>0&&curx<width&&cury>0&&cury<height)

    {

        //ShowCursor(0); //隐藏系统鼠标指针

        CEGUI::MouseCursor::getSingleton().show();

        CEGUI::System::getSingleton().injectMousePosition(curx,cury);

    }else

    {

        CEGUI::MouseCursor::getSingleton().hide();

    }

    

    return true;

}



bool  GuiFrameListener::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id) 

{

    CEGUI::System::getSingleton().injectMouseButtonDown(convertOgreButtonToCegui(id));

    return true;

}



bool  GuiFrameListener::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id )

{

    CEGUI::System::getSingleton().injectMouseButtonUp(convertOgreButtonToCegui(id));

    return true;

}

void GuiFrameListener::doNumKeyboard(OIS::KeyEvent &evt)

{

    switch (evt.key)

    {

    case OIS::KeyCode::KC_NUMPAD0:

        {

            evt.text=48;

        }

        break;

    case OIS::KeyCode::KC_NUMPAD1:

        {

            evt.text=49;

        }

        break;

    case OIS::KeyCode::KC_NUMPAD2:

        {

            evt.text=50;

        }

        break;

    case OIS::KeyCode::KC_NUMPAD3:

        {

            evt.text=51;

        }

        break;

    case OIS::KeyCode::KC_NUMPAD4:

        {

            evt.text=52;

        }

        break;

    case OIS::KeyCode::KC_NUMPAD5:

        {

            evt.text=53;

        }

        break;

    case OIS::KeyCode::KC_NUMPAD6:

        {

            evt.text=54;

        }

        break;

    case OIS::KeyCode::KC_NUMPAD7:

        {

            evt.text=55;

        }

        break;

    case OIS::KeyCode::KC_NUMPAD8:

        {

            evt.text=56;

        }

        break;

    case OIS::KeyCode::KC_NUMPAD9:

        {

            evt.text=57;

        }

        break;

    }

}

bool  GuiFrameListener::keyPressed(const OIS::KeyEvent &evt )

{

    //if(evt.key==OIS::KC_ESCAPE)

    //{

    //    mShoutdownRequested=true;

    //    return true;

    //}



    OIS::KeyEvent cEvent=evt;

    doNumKeyboard(cEvent);

    CEGUI::System::getSingleton().injectKeyDown(cEvent.key);

    CEGUI::System::getSingleton().injectChar(cEvent.text);



    switch (evt.key)

    {

    case OIS::KC_ESCAPE: 

        mShoutdownRequested = true;

        break;



    case OIS::KC_UP:

    case OIS::KC_W:



        break;



    case OIS::KC_DOWN:

    case OIS::KC_S:



        break;



    case OIS::KC_LEFT:

    case OIS::KC_A:



        break;



    case OIS::KC_RIGHT:

    case OIS::KC_D:



        break;



    case OIS::KC_PGDOWN:

    case OIS::KC_E:



        break;



    case OIS::KC_PGUP:

    case OIS::KC_Q:



        break;

    }





    return true;

}



bool  GuiFrameListener::keyReleased(const OIS::KeyEvent &evt )

{

    CEGUI::System::getSingleton().injectKeyUp(evt.key);

    switch (evt.key)

    {

    case OIS::KC_UP:

    case OIS::KC_W:

        break;



    case OIS::KC_DOWN:

    case OIS::KC_S:



        break;



    case OIS::KC_LEFT:

    case OIS::KC_A:



        break;



    case OIS::KC_RIGHT:

    case OIS::KC_D:



        break;



    case OIS::KC_PGDOWN:

    case OIS::KC_E:



        break;



    case OIS::KC_PGUP:

    case OIS::KC_Q:

        break;

    }





    return true;

}

 

 

你可能感兴趣的:(GUI)