首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Ogre3D在Windows中关注MouseOver

使用Ogre3D在Windows中关注MouseOver
EN

Stack Overflow用户
提问于 2012-03-07 06:35:28
回答 1查看 842关注 0票数 1

我有一个使用Ogre3D创建多个渲染窗口的应用程序,并且我正在使用发布的解决方案here来支持对这些窗口的非独占鼠标输入。然而,我发现我必须在渲染窗口重新获得焦点之前物理地单击它,而我真的希望渲染窗口在鼠标悬停事件上获得焦点。是否可以在Ogre3D/OIS中捕获未聚焦的渲染窗口上的鼠标悬停事件,然后设置渲染窗口的焦点?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-08 22:02:35

为了在Windows中使用Ogre3D支持这种功能,我必须实现一个单例对象,该对象保存所有实例化显示的集合。

代码语言:javascript
复制
class InputProcessor
{
    /// @name Types
    /// @{
public:
    /// @}

    /// @name InputProcessor implementation
    /// @{
public:
    void addDisplay(Display* _pDisplay);

    bool processMouseMoved(int _x, int _y, int _z, int _keyModifier);
    bool processMousePressed(int _keyModifier, int _id);
    bool processMouseReleased(int _keyModifier, int _id);

    static InputProcessor& getSingleton();
    /// @}

    /// @name 'Structors
    /// @{
private:
     InputProcessor();
    ~InputProcessor();
    /// @}

    /// @name Member Variables
    /// @{
private:
    typedef std::set<Display*>     Displays_type;
    Displays_type                  m_displays;
    /// @}

};  // class InputProcessor

然后,在我的UIFrameListener (它派生自Ogre3D的ExampleFrameListener)中,我将鼠标窗口坐标转换为全局屏幕坐标。如果鼠标恰好位于窗口区域之外,则将鼠标的相对移动应用于最后记录的鼠标位置;否则,仅应用窗口内的绝对鼠标位置:

代码语言:javascript
复制
bool
UIFrameListener::mouseMoved(const OIS::MouseEvent& e)
{
    int keyModifierState = GetKeyModifierState();
    int windowLeft = m_display.getLeft();
    int windowTop = m_display.getTop();
    int windowWidth = m_display.m_pWindow->getWidth();
    int windowHeight = m_display.m_pWindow->getHeight();

    if (e.state.X.abs != 0 && e.state.X.abs != windowWidth)
    {
        m_lastX = e.state.X.abs;
    }
    else
    {
        m_lastX += e.state.X.rel;
    }
    int x = windowLeft + (m_display.m_width * m_lastX) / windowWidth;

    if (e.state.Y.abs != 0 && e.state.Y.abs != windowHeight)
    {
        m_lastY = e.state.Y.abs;
    }
    else
    {
        m_lastY += e.state.Y.rel;
    }
    int y = windowTop + (m_display.m_height * m_lastY) / windowHeight;

    int z = 0;
    if (e.state.Z.rel != 0)
    {
        z = e.state.Z.rel / -120;
    }

    return InputProcessor::getSingleton().processMouseMoved(x, y, z, keyModifierState);
}

InputProcessor::processMouseMoved()中,我确定鼠标光标在哪个窗口中(如果有),然后适当地设置焦点,即

代码语言:javascript
复制
bool
InputProcessor::processMouseMoved(int _x,
                                  int _y,
                                  int _z,
                                  int _keyModifier)
{
    bool found = false;

    Displays_type::iterator iter = m_displays.begin();
    while (iter != m_displays.end() && !found)
    {
        int left = (*iter)->getLeft();
        int top = (*iter)->getTop();
        int width = (*iter)->m_pWindow->getWidth();
        int height = (*iter)->m_pWindow->getHeight();

        if (left <= _x && left + width  > _x &&
            top  <= _y && top  + height > _y)
        {
            found = true;
        }
        else
        {
            iter++;
        }
    }

    if (iter != m_displays.end())
    {
        int left = (*iter)->getLeft();
        int top = (*iter)->getTop();

        (*iter)->m_pContext->ProcessMouseMove(
            _x - left, _y - top, _keyModifier
        );

        (*iter)->m_pContext->ProcessMouseWheel(_z, _keyModifier);

        if (!(*iter)->hasFocus())
        {
            (*iter)->setFocus(true);
        }
    }

    return true;
}

Display的实现中,我有一个Display::setFocus()方法,它将焦点设置在适当的窗口上:

代码语言:javascript
复制
void
Display::setFocus(bool _hasFocus)
{
    if (m_handle != NULL && _hasFocus)
    {
        SetFocus(m_handle);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9593016

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档