Ogre3D嵌入Qt框架
来源:互联网 发布:阿肆预谋邂逅 知乎 编辑:程序博客网 时间:2024/06/04 18:46
按照经典的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就可以了。
class OgreView : public QWidget { Q_OBJECT public: OgreView(QWidget* parent ); ~OgreView(); //QSize minimumSizeHint() const; //QSize sizeHint() const; protected: void setupView()//创建Ogre使用的内容,场景内容; void update();//通过它,手动更新场景内容 void setupResources();// void createScene(); void createLight(); void resizeEvent(QResizeEvent* evt);//窗口可能缩放 void timerEvent(QTimerEvent* evt);//可以设一时钟来更新窗口 void paintEvent(QPaintEvent* evt);//呵,当然得处理了 //消息响应 void keyPressEvent(QKeyEvent* evt); void keyReleaseEvent(QKeyEvent* evt); void mousePressEvent(QMouseEvent* evt); void mouseReleaseEvent(QMouseEvent* evt); void mouseMoveEvent(QMouseEvent* evt); void wheelEvent(QWheelEvent* evt); //有关Ogre Ogre::RenderWindow* mRenderWindow; Ogre::SceneManager* mSceneMgr; Ogre::Camera* mCamera; Ogre::Viewport* mVp; Ogre::Root* mRoot; Ogre::Light* mainLight; Ogre::Entity* mainEnt; Ogre::SceneNode* mainNode; //一些控制变量,没有完全列出 Ogre::Vector3 mDirection; Ogre::Real mRotate; }; //cpp文件中的内容(部分) OgreView::OgreView(QWidget* parent) : QWidget(parent,Qt::WFlags(Qt::MSWindowsOwnDC)) { mRenderWindow = NULL; mSceneMgr = NULL; mVp = NULL; mainEnt = NULL; mainNode = NULL; //....还有一些控制变量的初始化 setupResources(); } OgreView::~OgreView() { // destroy Viewport and RenderWindow if( mVp ) { mRenderWindow->removeViewport(mVp->getZOrder()); mVp = 0; } Ogre::Root::getSingleton().detachRenderTarget(mRenderWindow); mRenderWindow = 0; if(mRoot != NULL){ delete mRoot; mRoot = 0; } } void OgreView::setupResources() { mRoot = new Ogre::Root(); Ogre::ConfigFile cf; cf.load("resources.cfg"); Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator(); Ogre::String secName, typeName, archName; while(seci.hasMoreElements()) { secName = seci.peekNextKey(); Ogre::ConfigFile::SettingsMultiMap* settings = seci.getNext(); Ogre::ConfigFile::SettingsMultiMap::iterator i; for(i=settings->begin(); i!=settings->end(); ++i){ typeName = i->first; archName = i->second; Ogre::ResourceGroupManager::getSingleton(). addResourceLocation(archName, typeName, secName); } } if(!mRoot->restoreConfig()) { mRoot->showConfigDialog(); } mRoot->initialise(false); //以上都是从Ogre普通程序照搬 } //没啥说的,代码比注释更明白 void OgreView::createScene() { mainEnt = mSceneMgr->createEntity("Head", "ogrehead.mesh"); mainNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); mainNode->attachObject(mainEnt); } void OgreView::createLight() { mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5)); mainLight = mSceneMgr->createLight("MainLight"); mainLight->setPosition(20,80,50); } void OgreView::setupView() { if(mRenderWindow) return; //createRenderWindow,当然必须得自己手工建窗口了,把窗口句柄扒出来.... Ogre::NameValuePairList params; params["externalWindowHandle"] = Ogre::StringConverter::toString((size_t)(HWND)winId()); mRenderWindow = mRoot->createRenderWindow("View", width(), height(), false, params); //SceneManager mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC); //setup camera & viewport mCamera = mSceneMgr->createCamera("PlayerCam"); mCamera->setPosition(Ogre::Vector3(0,0,80)); mCamera->lookAt(Ogre::Vector3(0,0,-300)); mCamera->setNearClipDistance(5); mVp = mRenderWindow->addViewport(mCamera); mVp->setBackgroundColour(Ogre::ColourValue(0, 0.0, 0.0, 1)); mCamera->setAspectRatio(Ogre::Real(mVp->getActualWidth()) / Ogre::Real(mVp->getActualHeight())); //resource Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); createScene(); createLight(); startTimer(2); } void OgreView::paintEvent(QPaintEvent *evt) { Q_UNUSED(evt); if(mRenderWindow == NULL) setupView(); update(); } void OgreView::timerEvent(QTimerEvent* evt) { Q_UNUSED(evt); update(); } void OgreView::update() { //手工更新场景内容,而不是进入到连续的循环中 if(mRenderWindow != NULL){ mRoot->_fireFrameStarted(); mRenderWindow->update(); mCamera->moveRelative(mDirection); mCamera->yaw(Ogre::Radian(angleX)); mCamera->pitch(Ogre::Radian(angleY)); mRoot->_fireFrameEnded(); } } void OgreView::resizeEvent(QResizeEvent *evt) { Q_UNUSED(evt); if (mRenderWindow != NULL){ mRenderWindow->windowMovedOrResized(); mCamera->setAspectRatio(Ogre::Real(mVp->getActualWidth()) / Ogre::Real(mVp->getActualHeight())); } } void OgreView::keyPressEvent(QKeyEvent* evt) { if(mainEnt != NULL && mainNode != NULL){ switch(evt->key()){ case Qt::Key_W: case Qt::Key_Up: rotX = -0.1; mainNode->pitch(Ogre::Radian(rotX)); break; case Qt::Key_S: case Qt::Key_Down: rotX = 0.1; mainNode->pitch(Ogre::Radian(rotX)); break; case Qt::Key_A: case Qt::Key_Left: rotY = -0.1; mainNode->yaw(Ogre::Radian(rotY)); break; case Qt::Key_D: case Qt::Key_Right: rotY = 0.1; mainNode->yaw(Ogre::Radian(rotY)); break; } } } void OgreView::mousePressEvent(QMouseEvent* evt) { if(evt->button() == Qt::LeftButton) mouseLeftPressed = true; if(evt->button() == Qt::RightButton){ mouseRightPressed = true; mousePos = Ogre::Vector2(evt->x(), evt->y()); } if(evt->button() == Qt::MidButton) mouseMiddleBtn = true; } void OgreView::wheelEvent(QWheelEvent* evt) { mDirection.z = -evt->delta()/12; update(); mDirection.z = 0; }
- Ogre3D嵌入Qt框架
- Ogre3D嵌入Qt框架
- Ogre3D嵌入Qt框架
- Ogre3D嵌入Qt框架
- Ogre3D嵌入Qt框架 之 小结
- Ogre3D嵌入Qt框架 之 秀图
- Ogre3D嵌入Qt框架 之 小结
- Ogre3D嵌入Qt框架 之 小结
- QT显示框架嵌入Vs控制台工程
- OSGEarth嵌入Qt的QGraphicsView框架(一)
- OSGEarth嵌入Qt的QGraphicsView框架(二)
- OGRE3D入门探索01:将渲染窗口嵌入到Win32主窗口
- Qt中嵌入OSG
- qt 嵌入 sdl
- Qt中嵌入Directx11
- Qt窗口嵌入
- QT中嵌入ActiveX
- SDl嵌入到QT中
- 四元数
- 【多维分析系列】大数据下的数据分析:Hadoop架构解析
- STL中的set容器的一点总结
- 库克发出正能量:让员工与家人共度佳节更重要
- 毕业后的五年拉开大家差距的原因在哪里
- Ogre3D嵌入Qt框架
- jquery异步上传
- C# 时钟设计
- Linux下配置NFS共享文件系统
- Ubuntu12.04自带输入法设置翻页
- Ogre导入模型
- 27-JAVA面向对象-接口
- linux mmc驱动cd_type定义
- Java中finalize()用法