相信很多OGRE的初学者被一个问题深深困扰,就是ogre调试窗口独占鼠标,无法将鼠标移出窗口,去做其他操作。只能通过alt+tab,切来切去,不管对于实验调试,还是实战写游戏使用,都是一个相当糟糕的体验。下面我们通过改写增加一部分代码来解决这个问题.
ogre1.6.5:楼主现在不在使用了,还在用这一版本的可以参照 http://blog.163.com/modingfa_002/blog/static/110925466201002123753962/写的文章,写的蛮全了
ogre1.7.x:本文讲的就是这个版本 ,http://blog.csdn.net/zhuxiaoyang2000/article/details/6559773 zhuxiaoyang2000 的文章也有说过,但是忘了对Tray也实现该功能,我这里就暂且啰嗦一把好了,当做补充
解决这个问题分两步:让鼠标移出窗体、移出窗体后的鼠标显示
让鼠标移出窗体:
修改SampleContext.h中的setupInput函数实现鼠标独占问题(全局)
virtual void setupInput() { //By pp.qin Dec-20-11,解决鼠标独占的问题 ShowCursor(0);//add OIS::ParamList pl; size_t winHandle = 0; std::ostringstream winHandleStr; mWindow->getCustomAttribute("WINDOW", &winHandle); winHandleStr << winHandle;
pl.insert(std::make_pair("WINDOW", winHandleStr.str())); pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND"))); //add pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));//add mInputMgr = OIS::InputManager::createInputSystem(pl); createInputDevices(); // create the specific input devices windowResized(mWindow); // do an initial adjustment of mouse area }
移出窗体后的鼠标显示:一出来后我们会发现个问题,就是ogre的窗体里有个鼠标,外面也有一个,这不符合使用习惯,应当隐藏
1.首先把我们选择例子的时候,那个主界面的设置修改一下,找到SdkTrays.h 中,class SdkTrayManager 的 bool injectMouseMove(const OIS::MouseEvent& evt)函数(注意这个头文件中有几个类class,有些类中也有同名的injectMouseMove()函数,别改错地方了),代码如下,记得在class SdkTrayManager的成员变量里添加一个bool isSysCursorVisible用来做show系统鼠标的标志;
#if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE bool injectMouseMove(const OIS::MultiTouchEvent& evt) #else bool injectMouseMove(const OIS::MouseEvent& evt) #endif { //解决鼠标独占问题,边界判断 add by pp.qin dec-21-11 if(evt.state.X.abs<mWindow->getViewport(0)->getActualLeft()+1 || evt.state.Y.abs<mWindow->getViewport(0)->getActualTop()+1 || evt.state.X.abs>mWindow->getViewport(0)->getActualLeft()+mWindow->getViewport(0)->getActualWidth()|| evt.state.Y.abs>mWindow->getViewport(0)->getActualTop()+mWindow->getViewport(0)->getActualHeight()) { if(!isSysCursorVisible) { ShowCursor(1); mCursorLayer->hide(); isSysCursorVisible=true; } } else { if(isSysCursorVisible) { ShowCursor(0); mCursorLayer->show(); isSysCursorVisible=false; } } //end dec-21-11 pp.qin 后面的代码不变 if (!mCursorLayer->isVisible()) return false; // don't process if cursor layer is invisible ...... ...... }
2.实例中的鼠标移出解决:当我们加载了例子之后,因为例子的class基本都是继承SdkSample的,所以我们可以在SdkSample.h里改动mouseMoved函数;或者当我们的例子example子类继承class SdkSample之后,将mouseMoved()重写,那么这段代码应该被加到重写的函数中。同样的记得在class SdkSampl成员变量中添加bool mSysMouseShowFlag 做判断标识。
virtual bool mouseMoved(const OIS::MouseEvent& evt) { //By pp.qin Dec-20-11 解决鼠标独占的问题 begin Dec-20-11 if(evt.state.X.abs<mWindow->getViewport(0)->getActualLeft()+1 || evt.state.Y.abs<mWindow->getViewport(0)->getActualTop()+1 || evt.state.X.abs>mWindow->getViewport(0)->getActualLeft()+mWindow->getViewport(0)->getActualWidth()|| evt.state.Y.abs>mWindow->getViewport(0)->getActualTop()+mWindow->getViewport(0)->getActualHeight()) { if(!mSysMouseShowFlag) { ShowCursor(1); mTrayMgr->hideCursor(); mSysMouseShowFlag=true; } } else { if(mSysMouseShowFlag) { ShowCursor(0); mTrayMgr->hideCursor(); mSysMouseShowFlag=false; } } //end dec-20-11 if (mTrayMgr->injectMouseMove(evt)) return true; mCameraMan->injectMouseMove(evt); return true; }
比如我新增例子中,mouseMove函数被重写,记得加添加鼠标移出判断:
bool Sample_bumper::mouseMoved(const OIS::MouseEvent &evt) { //当打开设置界面UI的时候 if(OpenSetupUI) mTrayMgr->injectMouseMove(evt); //若是L/R鼠标键,隐藏鼠标光标,转动 if(mMouseRightDown) { mCamNode->yaw(Ogre::Degree(-evt.state.X.rel*MOUSEROLLSPEED),Ogre::Node::TS_WORLD); mCamNode->pitch(Ogre::Degree(-evt.state.Y.rel*MOUSEROLLSPEED)); //evt.state.X.abs-=evt.state.X.rel; //evt.state.Y.abs-=evt.state.Y.rel; } //否则单纯的光标移动 else { mTrayMgr->setCursorPos(xAbsCursor,yAbsCursor); } //double check 防止某些情况下鼠标消失 if(!(mMouseRightDown || mMouseLeftDown)) mTrayMgr->showCursor(); //鼠标滚轮,拉近远离视角 if(evt.state.Z.rel!=0) { mCamera->moveRelative(Ogre::Vector3(0,0,-evt.state.Z.rel*0.40f*MOUSEROLLSPEED)); } //解决鼠标独占问题,边界判断 begin if(evt.state.X.abs<mWindow->getViewport(0)->getActualLeft()+1 || evt.state.Y.abs<mWindow->getViewport(0)->getActualTop()+1 || evt.state.X.abs>mWindow->getViewport(0)->getActualLeft()+mWindow->getViewport(0)->getActualWidth()|| evt.state.Y.abs>mWindow->getViewport(0)->getActualTop()+mWindow->getViewport(0)->getActualHeight()) { if(!mSysMouseShowFlag) { ShowCursor(1); mTrayMgr->hideCursor(); mSysMouseShowFlag=true; } } else { if(mSysMouseShowFlag) { ShowCursor(0); mTrayMgr->hideCursor(); mSysMouseShowFlag=false; } } //end 鼠标移出修改结束 //for DEBUG Ogre::String debugMessage1; debugMessage1="cursorPos: "+Ogre::StringConverter::toString(CursorPosBeforeHide.x)+","+Ogre::StringConverter::toString(CursorPosBeforeHide.y); mInfoLabel->setCaption(debugMessage1); return true; }