现在的位置: 首页 > 综合 > 正文

Ogre3D嵌入Qt框架

2014年04月05日 ⁄ 综合 ⁄ 共 7422字 ⁄ 字号 评论关闭

 按照经典的Qt程序结构,应该有一个从QMainWindow继承而来的MainWindow,让它做为主窗口,然后子类化一个QWidget,它做为主窗口的"中心挂件",能过封装Ogre的部分功能,实现用Ogre对该窗体的绘制。首先,如何把Ogre这个引擎发动,不断驱动其进行工作。Qt也需要告诉Ogre如何把渲染的内容画到指定的窗口中去,以及用哪种方式更新窗口中的内容。

         当键盘或鼠标消息来的时候,如何通知Ogre进行响应。从Ogre这边来看,就是如何把Ogre的功能,分布到Qt的各个部分。而且与一般的ogre程序不同,不是进入到连续的循环中(一般的ogre程序中,通过执行mRoot->startRendering();语句进入一个不停渲染循环,通过预先安插好的帧侦听器来对消息进行响应,对程序逻辑进行处理)而可以是“必要时”对窗口进行更新。而且与一般ogre程序不同,由于Qt自身可以检测输入设备消息,因此,OIS不再需要。
         把Ogre中的内容嵌入到Qt,从形式来看可以许多种,也就是说可以把相关Ogre的部分拆成不同部分,按照作者的需要封装在Qt中的不同部分。比如,Ogre中描述抽象的“引擎”概念的部分(Root等),因为我们想一但应用程序启动,就应该让Ogre引擎启动了,那么这些部分可以用QApplication封装,而且RenderWindow,与Qt中的QWidget概念上是关联的,所以就用QWidget来封装。出于简单的原因,我把Ogre都封装从QWidget继承而来的OgreView中了。很显然,主要考虑OgreView就可以了。

  1. class  OgreView  :  public  QWidget    
  2. {    
  3.     Q_OBJECT    
  4.         
  5. public:    
  6.     OgreView(QWidget*  parent  );    
  7.     ~OgreView();    
  8.     //QSize  minimumSizeHint()  const;    
  9.     //QSize  sizeHint()  const;    
  10. protected:    
  11.     void  setupView()//创建Ogre使用的内容,场景内容;    
  12.         void  update();//通过它,手动更新场景内容    
  13.     void  setupResources();//    
  14.     void  createScene();    
  15.     void  createLight();    
  16.     void  resizeEvent(QResizeEvent*  evt);//窗口可能缩放    
  17.     void  timerEvent(QTimerEvent*  evt);//可以设一时钟来更新窗口    
  18.     void  paintEvent(QPaintEvent*  evt);//呵,当然得处理了    
  19.     //消息响应    
  20.     void  keyPressEvent(QKeyEvent*  evt);    
  21.     void  keyReleaseEvent(QKeyEvent*  evt);    
  22.     void  mousePressEvent(QMouseEvent*  evt);    
  23.     void  mouseReleaseEvent(QMouseEvent*  evt);    
  24.     void  mouseMoveEvent(QMouseEvent*  evt);    
  25.     void  wheelEvent(QWheelEvent*  evt);    
  26.     
  27.     //有关Ogre    
  28.     Ogre::RenderWindow*  mRenderWindow;    
  29.     Ogre::SceneManager*  mSceneMgr;    
  30.     Ogre::Camera*  mCamera;    
  31.     Ogre::Viewport*  mVp;    
  32.     Ogre::Root*  mRoot;    
  33.     Ogre::Light*  mainLight;    
  34.     Ogre::Entity*  mainEnt;    
  35.     Ogre::SceneNode*  mainNode;    
  36.     //一些控制变量,没有完全列出    
  37.     Ogre::Vector3  mDirection;    
  38.     Ogre::Real  mRotate;    
  39.     
  40. };    
  41. //cpp文件中的内容(部分)    
  42. OgreView::OgreView(QWidget*  parent) : QWidget(parent,Qt::WFlags(Qt::MSWindowsOwnDC))    
  43. {    
  44.     mRenderWindow  =  NULL;    
  45.     mSceneMgr  =  NULL;    
  46.     mVp  =  NULL;    
  47.     mainEnt  =  NULL;    
  48.     mainNode  =  NULL;    
  49.     //....还有一些控制变量的初始化    
  50.     setupResources();    
  51. }    
  52. OgreView::~OgreView()    
  53. {    
  54.     //  destroy  Viewport  and  RenderWindow    
  55.     if(  mVp  )    
  56.     {    
  57.         mRenderWindow->removeViewport(mVp->getZOrder());    
  58.         mVp  =  0;    
  59.     }    
  60.     
  61.     Ogre::Root::getSingleton().detachRenderTarget(mRenderWindow);    
  62.     mRenderWindow  =  0;    
  63.     
  64.     if(mRoot  !=  NULL){    
  65.         delete  mRoot;    
  66.         mRoot  =  0;    
  67.     }    
  68. }    
  69. void  OgreView::setupResources()    
  70. {    
  71.     mRoot  =  new  Ogre::Root();    
  72.     Ogre::ConfigFile  cf;    
  73.     cf.load("resources.cfg");    
  74.     
  75.     Ogre::ConfigFile::SectionIterator  seci  =  cf.getSectionIterator();    
  76.     Ogre::String  secName,  typeName,  archName;    
  77.     while(seci.hasMoreElements())    
  78.     {    
  79.         secName  =  seci.peekNextKey();    
  80.         Ogre::ConfigFile::SettingsMultiMap*  settings  =  seci.getNext();    
  81.         Ogre::ConfigFile::SettingsMultiMap::iterator  i;    
  82.         for(i=settings->begin();  i!=settings->end();  ++i){    
  83.             typeName  =  i->first;    
  84.             archName  =  i->second;    
  85.             Ogre::ResourceGroupManager::getSingleton().
  86.   addResourceLocation(archName,  typeName,  secName);    
  87.         }    
  88.     }    
  89.     
  90.     if(!mRoot->restoreConfig())    
  91.     {    
  92.         mRoot->showConfigDialog();    
  93.     }    
  94.     mRoot->initialise(false);    
  95.     //以上都是从Ogre普通程序照搬    
  96. }    
  97. //没啥说的,代码比注释更明白    
  98. void  OgreView::createScene()    
  99. {    
  100.     mainEnt  =  mSceneMgr->createEntity("Head",  "ogrehead.mesh");    
  101.     mainNode  =  mSceneMgr->getRootSceneNode()->createChildSceneNode();    
  102.     mainNode->attachObject(mainEnt);    
  103. }    
  104. void  OgreView::createLight()    
  105. {    
  106.     
  107.         mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5,  0.5,  0.5));    
  108.         mainLight  =  mSceneMgr->createLight("MainLight");    
  109.         mainLight->setPosition(20,80,50);    
  110. }    
  111. void  OgreView::setupView()    
  112. {    
  113.         if(mRenderWindow)    
  114.                 return;    
  115.     //createRenderWindow,当然必须得自己手工建窗口了,把窗口句柄扒出来....    
  116.     
  117.     Ogre::NameValuePairList  params;    
  118.     params["externalWindowHandle"]  =  Ogre::StringConverter::toString((size_t)(HWND)winId());    
  119.     mRenderWindow  =  mRoot->createRenderWindow("View",  width(), height(),  false,  params);    
  120.     //SceneManager    
  121.     mSceneMgr  =  mRoot->createSceneManager(Ogre::ST_GENERIC);    
  122.     //setup  camera  &  viewport      
  123.     mCamera  =  mSceneMgr->createCamera("PlayerCam");    
  124.     mCamera->setPosition(Ogre::Vector3(0,0,80));    
  125.     mCamera->lookAt(Ogre::Vector3(0,0,-300));    
  126.     mCamera->setNearClipDistance(5);    
  127.     mVp  =  mRenderWindow->addViewport(mCamera);    
  128.     mVp->setBackgroundColour(Ogre::ColourValue(0,  0.0,  0.0,  1));    
  129.     mCamera->setAspectRatio(Ogre::Real(mVp->getActualWidth())  /  
  130.     Ogre::Real(mVp->getActualHeight()));    
  131.     //resource    
  132.     Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();    
  133.     createScene();    
  134.     createLight();    
  135.     startTimer(2);    
  136. }    
  137. void  OgreView::paintEvent(QPaintEvent  *evt)    
  138. {    
  139.     Q_UNUSED(evt);    
  140.         if(mRenderWindow  ==  NULL)    
  141.                 setupView();    
  142.     update();    
  143. }    
  144. void  OgreView::timerEvent(QTimerEvent*  evt)    
  145. {    
  146.     Q_UNUSED(evt);    
  147.     update();    
  148.     
  149. }    
  150. void  OgreView::update()    
  151. {    
  152.     //手工更新场景内容,而不是进入到连续的循环中    
  153.     if(mRenderWindow  !=  NULL){    
  154.         mRoot->_fireFrameStarted();    
  155.         mRenderWindow->update();    
  156.         
  157.         mCamera->moveRelative(mDirection);    
  158.         mCamera->yaw(Ogre::Radian(angleX));    
  159.         mCamera->pitch(Ogre::Radian(angleY));    
  160.         
  161.         mRoot->_fireFrameEnded();    
  162.     }    
  163. }    
  164. void  OgreView::resizeEvent(QResizeEvent  *evt)    
  165. {    
  166.     Q_UNUSED(evt);    
  167.     if  (mRenderWindow  !=  NULL){    
  168.         mRenderWindow->windowMovedOrResized();    
  169.         mCamera->setAspectRatio(Ogre::Real(mVp->getActualWidth())  /  Ogre::Real(mVp->getActualHeight()));    
  170.     }    
  171. }    
  172. void  OgreView::keyPressEvent(QKeyEvent*  evt)    
  173. {    
  174.     if(mainEnt  !=  NULL  &&  mainNode  !=  NULL){    
  175.         switch(evt->key()){    
  176.         case  Qt::Key_W:    
  177.         case  Qt::Key_Up:    
  178.             rotX  =  -0.1;    
  179.             mainNode->pitch(Ogre::Radian(rotX));    
  180.             break;    
  181.         case  Qt::Key_S:    
  182.         case  Qt::Key_Down:    
  183.             rotX  =  0.1;    
  184.             mainNode->pitch(Ogre::Radian(rotX));    
  185.             break;    
  186.         case  Qt::Key_A:    
  187.         case  Qt::Key_Left:    
  188.             rotY  =  -0.1;    
  189.             mainNode->yaw(Ogre::Radian(rotY));    
  190.             break;    
  191.         case  Qt::Key_D:    
  192.         case  Qt::Key_Right:    
  193.             rotY  =  0.1;    
  194.             mainNode->yaw(Ogre::Radian(rotY));    
  195.             break;    
  196.         }    
  197.     }    
  198. }    
  199. void  OgreView::mousePressEvent(QMouseEvent*  evt)    
  200. {    
  201.     if(evt->button()  ==  Qt::LeftButton)    
  202.         mouseLeftPressed  =  true;    
  203.     if(evt->button()  ==  Qt::RightButton){    
  204.         mouseRightPressed  =  true;    
  205.         mousePos  =  Ogre::Vector2(evt->x(),  evt->y());    
  206.     }    
  207.     if(evt->button()  ==  Qt::MidButton)    
  208.         mouseMiddleBtn  =  true;    
  209. }    
  210. void  OgreView::wheelEvent(QWheelEvent*  evt)    
  211. {    
  212.     mDirection.z  =  -evt->delta()/12;    
  213.     update();    
  214.     mDirection.z  =  0;    
  215. }    

抱歉!评论已关闭.