2012-03-06 3 views
1

Ogre3D를 사용하여 여러 개의 렌더링 윈도우를 만드는 응용 프로그램이 있으며이 윈도우에 비 독점적 마우스 입력을 지원하기 위해 here 게시 된 솔루션을 사용하고 있습니다. 그러나 포커스를 되찾기 전에 실제로 렌더링 윈도우를 클릭해야한다는 것을 알았지 만, 마우스 오버 이벤트에 초점을 맞추기 위해 렌더링 윈도우를 실제로 사용하고 싶습니다. Ogre3D/OIS의 unfocused 렌더 윈도우에서 mouseover 이벤트를 캡처 한 다음 렌더 윈도우의 포커스를 설정할 수 있습니까?Ogre3D를 사용하여 Windows에서 MouseOver에 초점

+1

을 알린다을 많은 바람에 ow 관리자들, 초점을 얻는 것은 창을 글꼴로 가져 오는 것을 의미합니다. 이러한 동작은 창 관리자에게 익숙한 사용자에게는 매우 드문 일입니다. –

+0

Duly 지적 - 내 특정 응용 프로그램에서 창문을 바둑판 식으로 배열하고 정적 위치를 가지고 있으며 실제로 제안한 동작이 필요합니다 ... – hatboyzero

+0

사실인데 왜 창문이 모두 들립니까? 타일 ​​된 뷰포트를 분리하여 렌더링 할 수 없습니까? –

답변

0

Windows에서 Ogre3D를 사용하여 이러한 종류의 기능을 지원하려면 인스턴스화 된 모든 디스플레이를 모아 둔 싱글 톤 객체를 구현해야했습니다.

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 

그런 다음, (Ogre3D의 ExampleFrameListener에서 유래) 내 UIFrameListener에, 나는 마우스 창이 글로벌 화면 좌표 좌표 변환. 마우스가 윈도우 영역 외부에있을 경우, 마지막으로 기록 된 마우스 위치에 상대적인 마우스 움직임을 적용합니다. 그렇지 않으면, 나는 단순히 창에서 절대 마우스 위치를 적용

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()에, 나는 마우스 커서 (있는 경우)에있는 창을 확인한 다음

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() 있습니다

void 
Display::setFocus(bool _hasFocus) 
{ 
    if (m_handle != NULL && _hasFocus) 
    { 
     SetFocus(m_handle); 
    } 
}