目前還沒有將QT、OSG和CEGUI結合的例子,OSG內建有osgcegui和osgviewerQT例子,但是將三者結合不是那麼簡單的事情,經過不斷的摸索和調試,解決了三者結合編程中的一系列問題,下面是最核心的實現CEGUI視窗類別的代碼,在視窗事件處理類中處理事件之前,要先判斷是否已經捕捉到CEGUI視窗,如果沒有捕捉到CEGUI視窗,則還要繼續判斷滑鼠是否落在CEGUI視窗內,是則return true,否則在為CEGUI注入視窗事件後return true。完整代碼如下:
#ifndef DOTESTGUI_H<br />#define DOTESTGUI_H</p><p>#include <qdebug.h></p><p>#include <osgDB/ReadFile><br />#include <osgUtil/Optimizer><br />#include <osgViewer/Viewer><br />#include <osg/CoordinateSystemNode><br />#include <osgGA/GUIEventAdapter></p><p>#include <CEGUI/CEGUI.h><br />#include <CEGUI/CEGUISystem.h><br />#include <CEGUI/RendererModules/OpenGL/CEGUIOpenGLRenderer.h><br />#include <CEGUI/CEGUIScriptModule.h><br />#include <CEGUI/CEGUIFontManager.h><br />#include <CEGUI/CEGUISchemeManager.h><br />#include <CEGUI/CEGUIWindowManager.h><br />#include <CEGUI/CEGUIExceptions.h></p><p>#include <iostream><br />/*<br /> 類CEGUIDrawable<br />*/<br />class CEGUIDrawable : public osg::Drawable<br />{<br />public:</p><p> CEGUIDrawable();</p><p> /** Copy constructor using CopyOp to manage deep vs shallow copy.*/<br /> CEGUIDrawable(const CEGUIDrawable& drawable,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):<br /> Drawable(drawable,copyop) {}</p><p> META_Object(osg,CEGUIDrawable);</p><p> void loadScheme(const std::string& scheme);<br /> void loadFont(const std::string& font);<br /> void loadLayout(const std::string& layout);</p><p> /** Sub routines for each edit panel.*/<br /> void initStaticText();<br /> void initSingleLineEdit();<br /> void initMultiLineEdit();<br /> bool isRadioSelected(const CEGUI::String& radio);<br /> bool isCheckboxSelected(const CEGUI::String& checkbox);<br /> /** Sets group- and selected for given radio name.*/<br /> void initRadio(const CEGUI::String& radio, int group, bool selected);</p><p> void subscribeEvent(const CEGUI::String& widget, const CEGUI::String& event, const CEGUI::Event::Subscriber& method);</p><p> void drawImplementation(osg::RenderInfo& renderInfo) const;</p><p>bool bCapture;<br />protected:</p><p> /** Called when user changes the scrollbar option of the multiline edit.*/<br /> bool vertScrollChangedHandler(const CEGUI::EventArgs& e);<br /> bool formatChangedHandler(const CEGUI::EventArgs&);<br /> bool quit(const CEGUI::EventArgs&);<br /> virtual ~CEGUIDrawable();</p><p> unsigned int _activeContextID;<br />};</p><p>/*<br /> 結構CEGUIEventCallback<br /> */<br />struct CEGUIEventCallback : public osgGA::GUIEventHandler<br />{<br /> CEGUIEventCallback() {}</p><p> /** do customized Event code. */<br /> virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa, osg::Object* obj, osg::NodeVisitor* nv)<br /> {<br />osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);</p><p> osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv);<br /> CEGUIDrawable* cd = dynamic_cast<CEGUIDrawable*>(obj);<br />if (!ev || !cd)<br />return false;</p><p>CEGUI::WindowManager& winMgr = CEGUI::WindowManager::getSingleton();<br />CEGUI::Window* window = winMgr.getWindow("TextDemo");<br />const CEGUI::URect rect = window->getArea();<br />int x = ea.getX();<br />int y = view->getCamera()->getViewport()->height() - ea.getY();<br />int width = view->getCamera()->getViewport()->width();<br />int height = view->getCamera()->getViewport()->height();<br />int minx = rect.d_min.d_x.d_scale * width + rect.d_min.d_x.d_offset;<br />int maxx = rect.d_max.d_x.d_scale * width + rect.d_max.d_x.d_offset;<br />int miny = rect.d_min.d_y.d_scale * height + rect.d_min.d_y.d_offset;<br />int maxy = rect.d_max.d_y.d_scale * height + rect.d_max.d_y.d_offset;</p><p>if (!cd->bCapture)<br />{<br />if (x < minx || x > maxx || y < miny || y > maxy)<br />{<br />qDebug() << "outside of CEGUI dialog/n";<br />return false;<br />}<br />}</p><p>{ //ea.setMouseYOrientation((osgGA::GUIEventAdapter::MouseYOrientation)1);<br />switch(ea.getEventType())<br />{<br />case(osgGA::GUIEventAdapter::DRAG):<br />case(osgGA::GUIEventAdapter::MOVE):<br />CEGUI::System::getSingleton().injectMousePosition(ea.getX(),ea.getWindowHeight() - ea.getY());<br />break;<br />case(osgGA::GUIEventAdapter::PUSH):<br />{<br />CEGUI::System::getSingleton().injectMousePosition(ea.getX(), ea.getWindowHeight() - ea.getY());</p><p>if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) // left<br />CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);</p><p>else if (ea.getButton() == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) // middle<br />CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton);</p><p>else if (ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) // right<br />CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton);</p><p>cd->bCapture = true;<br />break;<br />}<br />case(osgGA::GUIEventAdapter::RELEASE):<br />{<br />CEGUI::System::getSingleton().injectMousePosition(ea.getX(), ea.getWindowHeight() - ea.getY());</p><p>if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) // left<br />CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton);</p><p>else if (ea.getButton() == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) // middle<br />CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::MiddleButton);</p><p>else if (ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) // right<br />CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::RightButton);</p><p>cd->bCapture = false;</p><p>break;<br />}<br />case(osgGA::GUIEventAdapter::DOUBLECLICK):<br />{<br />// do we need to do something special here to handle double click??? Will just assume button down for now.<br />CEGUI::System::getSingleton().injectMousePosition(ea.getX(), ea.getWindowHeight() - ea.getY());</p><p>if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) // left<br />CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);</p><p>else if (ea.getButton() == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON) // middle<br />CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton);</p><p>else if (ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) // right<br />CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton);</p><p>break;<br />}</p><p> case(osgGA::GUIEventAdapter::KEYDOWN):<br />CEGUI::System::getSingleton().injectKeyDown( static_cast<CEGUI::uint>(ea.getKey()) );<br />CEGUI::System::getSingleton().injectChar( static_cast<CEGUI::utf32>( ea.getKey() ) );<br />break;<br />case(osgGA::GUIEventAdapter::KEYUP):<br />CEGUI::System::getSingleton().injectKeyUp( static_cast<CEGUI::uint>(ea.getKey()) );<br />break;<br />default:<br />break;<br />}</p><p>qDebug() << "inside of CEGUI dialog/n";<br />qDebug() << "window: " << width << "," << height << "/n";<br />qDebug() << "cur:" << x << "," << y << " ||| " << "extent: " << minx << "," << maxx << "," << miny << "," << maxy << "/n";</p><p>return true;<br />}<br /> }<br />};</p><p>#endif // DOTESTGUI_H<br />