Ogre3D嵌入Qt框架
按照经典的Qt程序结构,应该有一个从QMainWindow继承而来的MainWindow,让它做为主窗口,然后子类化一个QWidget,它做为主窗口的"中心挂件",能过封装Ogre的部分功能,实现用Ogre对该窗体的绘制。首先,如何把Ogre这个引擎发动,不断驱动其进行工作。Qt也需要告诉Ogre如何把渲染的内容画到指定的窗口中去,以及用哪种方式更新窗口中的内容。
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框架相关推荐
- 将OSG嵌入QT窗口系统中,实现拖拽界面
将OSG嵌入QT窗口系统中,实现拖拽界面 一.原理 OSG底层使用的是OpenGL图形系统,QT也增加了对OpenGL的支持,因此,可以通过QT的OpenGL模块,实现将OSG窗口嵌入到QT中,这样可 ...
- C#的WinForm中嵌入Qt界面库
C#的WinForm中嵌入Qt界面库 为何会有如此奇葩需求 一处代码,多处运行 C#有两种写界面的框架,winFrom和WPF,这二者写的界面可以相互调用,但C#编写的界面组件在非托管C++虽然理论上 ...
- 半小时训练亿级规模知识图谱,亚马逊AI开源知识图谱嵌入表示框架DGL-KE
出品 | AI科技大本营(ID:rgznai100) 知识图谱 (Knowledge Graph)作为一个重要的技术,在近几年里被广泛运用在了信息检索,自然语言处理,以及推荐系统等各种领域.学习知识图 ...
- 半小时训练亿级规模知识图谱,亚马逊AI开源知识图谱嵌入表示框架
来源:AI 科技大本营 本文约2300字,建议阅读9分钟 亚马逊 AI 团队开源了一款专门针对大规模知识图谱嵌入表示的新训练框架 DGL-KE,能让研究人员和工业界用户方便.快速地在大规模知识图谱数据 ...
- HTTP中CORS跨域请求的实现(C++|Qt框架实现)
目录 背景 关键 演示及源码 背景 HTTP中CORS跨域请求,可以获取其他服务器的数据: 这里用Qt框架实现! 逻辑如下: 浏览器访问127.0.0.1:80端口!80端口请求了127.0.0.1: ...
- QT 框架搭建,用最原始的方法实现简单的塔防游戏 | 原力计划
作者 | 白家名 责编 | 王晓曼 出品 | CSDN博客 本文作者使用 QT 框架写了一个塔防游戏程序,该程序中实现了购买炮塔.炮塔升级.怪物按照设定路径移动.炮塔自动寻找范围内目标.朝目标怪物发射 ...
- 基于海思平台与QT框架的高效视频显示
首先,不涉及视频解码,仅涉及解码之后的视频缩放.颜色空间转换(如YUV转RGB).贴图.本文主要说明的是在QT框架没有使用OpenGl的情况下,如何让解码后的视频更高效的展示出来. 海思底层解码出来的 ...
- Qt框架与STL库之间的巅峰对决:差异、优缺点及适用场景
Qt框架与STL库之间的巅峰对决:差异.优缺点及适用场景 引言 对比的重要性 Qt框架与STL库简介 博客内容概览 Qt框架基础 Qt框架的特点与组成 Qt的信号槽机制 Qt容器类简介 数据结构的对比 ...
- Qt框架之情人节玫瑰花案例项目
Qt框架之情人节玫瑰花案例项目 本项目是源自Qt框架书写的一个项目,Qt版本选择的是Qt 5.3.1 该版本bug较少,出错几率小,适合入门者学习, 源码我放在CSDN资源了和github主页了. C ...
最新文章
- vs2008中如何在项目属性中切换“图形形式”和“控制台形式”——即调出或消除黑窗口
- 计算机设备安全检查表,信息安全检查表
- 为什么大部分程序员看不起PHP这门语言?
- MySQL提供了以下三种方法用于获取数据库对象的元数据
- 蚂蚁上市P8身价超亿,丢给我这几个牛逼的公众号
- 世界粮农组织五大健康食品_粮农组织的完整形式是什么?
- AAAI 2020 | 首个使用 NAS 设计的 GCN,达到动作识别SOTA,代码将开源
- ZOJ - 2865 A very easy task
- java便利店库存管理系统_便利店库存管理系统可以做什么?
- 无刷直流电机计算转速
- 工作站Linux双显卡BIOS设置,在BIOS Setup里面设置双显卡机型的双显卡模式教程
- package 包名; ^ zip END header not found
- 【Chapter 1】架构的结构
- 微信小程序留言板设计
- Android自定义控件开发入门与实战(7)SVG动画,android底层架构
- Java基础语法(十三):throw和throws
- 网页卡顿是网站服务器,想解决网站卡顿情况就用这几种诀窍,进来看看
- Python 基于csv 读取文本文件提示:‘gbk‘ codec can‘t decode byte 0xbf in position 2: illegal multibyte sequence
- 移动硬盘,U盘出现USBC病毒乱码恢复的可能性分析
- 【学习历程】05 安装大数据集群前的环境准备
热门文章
- zigbee协议栈OSAL分析
- 矩形脉冲信号合成_矩形脉冲信号的分解和合成
- ChatGPT来了,软件测试工程师距离失业还远吗?
- python调用java接口
- 昆仑通态触摸屏与台达变频器RS485通讯程序,不经过plc直接用昆仑通态触摸屏的串口对台达变频器进行modbus通讯
- QGraphicsScene Class
- Verilog Tutorial(5)使用always块实现时序逻辑电路
- 在华为eNSP上操作配置“静态路由”实验
- 【.NET 基础】——CLR、BCL、DLL、Assembly
- h3c 路由器虚拟机dhcp服务器,H3C三层交换机DHCP服务器配置实例