hatboyzero
hatboyzero

Reputation: 1937

Ogre3D, Multiple Monitors, and the Mouse Cursor

I am developing an application that requires multihead rendering in OpenGL. Right now, I can render to multiple screens, but the travel of my mouse cursor is limited to a single screen. However, I'd like to be able to use the mouse cursor on all of the rendered screens.

Has anyone run into this same issue, and if so, how did you go about resolving it?

Upvotes: 4

Views: 1970

Answers (1)

hatboyzero
hatboyzero

Reputation: 1937

I found a working solution for this. First, I had to instantiate my Ogre::RenderWindow objects in windowed mode rather than full-screen mode -- full-screen mode was emulated easy enough by instantiating the Ogre::RenderWindow objects without borders like so:

Ogre::NameValuePairList options;
options["left"] = "0";
options["top"] = "0";
options["border"] = "none";
options["monitorIndex"] = "0";
m_pVisWindow[0] = mRoot->createRenderWindow("Window1", 1920, 1200, false, &options);

options["monitorIndex"] = "1";
m_pVizWindow[1] = mRoot->createRenderWindow("Window2", 1920, 1200, false, &options);

options["monitorIndex"] = "2";
m_pVizWindow[2] = mRoot->createRenderWindow("Window3", 1920, 1200, false, &options);

options["monitorIndex"] = "3";
m_pVizWindow[3] = mRoot->createRenderWindow("Window4", 1920, 1200, false, &options);

options["monitorIndex"] = "4";
m_pVizWindow[4] = mRoot->createRenderWindow("Window5", 1920, 1200, false, &options);

options["monitorIndex"] = "5";
m_pVizWindow[5] = mRoot->createRenderWindow("Window6", 1920, 1200, false, &options);

In the constructor of the Ogre::FrameListener attached to each Ogre::RenderWindow (which in this case, inherits from ExampleFrameListener, I essentially had to destroy the existing mInputManager and instantiate a new one with parameters for configuring OIS for non-exclusive input. A more detailed description of how and why to do this can be found here.

mInputManager->destroyInputObject(mMouse);
mInputManager->destroyInputObject(mKeyboard);
mInputManager->destroyInputObject(mJoy);
OIS::InputManager::destroyInputSystem(mInputManager);

// override OIS construction to avoid grabbing mouse
OIS::ParamList pl;
size_t windowHnd = 0;
std::ostringstream windowHndStr;

window->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd;
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
#if defined OIS_WIN32_PLATFORM
pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
#elif defined OIS_LINUX_PLATFORM
pl.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
pl.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
pl.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
#endif

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

//Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse)
mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, false ));
mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, false ));
try {
    mJoy = static_cast<OIS::JoyStick*>(mInputManager->createInputObject( OIS::OISJoyStick, false ));
}
catch(...) {
    mJoy = 0;
}

I do still have to physically click on a specific render window in order to give it focus, so it would be nice if there was a way to grant focus to a render window on a mouseover event -- however, this suits my needs for now...

Upvotes: 6

Related Questions