OGRE与Qt的结合(一)----使用OGRE渲染QWidget
来源:互联网 发布:模拟科目二练车软件 编辑:程序博客网 时间:2024/05/19 05:31
最近几天开始重新学习Ogre,这次从源码编译了Ogre2.1,编译过程基本跟Ogre1.8.1类似,连第三方依赖库都是用的官网推荐的以前版本的,此处不多说了,网上有很多教程,现在给出下载连接。
Ogre2.1的源码: https://bitbucket.org/sinbad/ogre/branch/v2-1
Dependencies: https://bitbucket.org/cabalistic/ogredeps
编译好Ogre后开始尝试将其嵌入到Qt中,发现网上的指导教程非常的少,而且含糊不清,对于想上手的人来说非常困难。发现Ogre的Wiki有现成的结合Qt配置方案,给出网址 http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Setting+Up+An+Application+-+QtCreator 参考。具体来说,主要是在Qt项目的pro文件中配置。以下是个人结合参考做出的Ogre渲染QWidget的例子。
1、新建一个Qt Widgets Application,在pro文件中添加配置信息如下
OGRE_HOME = D:/OGRE/Ogre2.1
LIBS *= user32.lib
LIBS += -L$${OGRE_HOME}/boost/lib
debug: LIBS += -L$${OGRE_HOME}/lib/debug
release: LIBS += -L$${OGRE_HOME}/lib/release
INCLUDEPATH += $${OGRE_HOME}/include
INCLUDEPATH += $${OGRE_HOME}/include/OGRE
INCLUDEPATH += $${OGRE_HOME}/include/OIS
INCLUDEPATH += $${OGRE_HOME}/boost
CONFIG(debug, debug|release){
LIBS *= -lOgreMain_d -lOIS_d -lOgreTerrain_d
DESTDIR = $${OGRE_HOME}/bin/debug
}
else{
LIBS *= -lOgreMain -lOIS -OgreTerrain
DESTDIR = $${OGRE_HOME}/bin/release
}2、新建类 TestOgre,并继承自QWidget。在TestOgre这个类中,实现创建Ogre的Root对象,定义资源,设置渲染引擎,创建渲染窗口,初始化资源,创建场景,
设置第三方库和插件库,创建帧监听器,启动渲染循环等工作。主要参考了Ogre Wiki的教程6
http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Basic+Tutorial+6&structure=Tutorials
TestOgre.h
#ifndef TESTOGRE_H
#define TESTOGRE_H
#include <QtGui>
#include <Ogre.h>
class TestOgre : public QWidget
{
Q_OBJECT
public:
TestOgre(QWidget *parent = 0);
~TestOgre();
// Override QWidget::paintEngine to return NULL
QPaintEngine* paintEngine() const; // Turn off QTs paint engine for the Ogre widget.
protected:
virtual void paintEvent(QPaintEvent *e);
virtual void resizeEvent(QResizeEvent *e);
virtual void showEvent(QShowEvent *e);
private:
void InitOgreSystem();
void SetupAndLoadResources();
void CreateScene();
private:
Ogre::Root* m_Root;
Ogre::SceneManager* m_SceneManager;
Ogre::RenderWindow* m_RenderWindow;
Ogre::Viewport* m_Viewport;
Ogre::Camera* m_Camera;
Ogre::String mPluginsCfg;
Ogre::String mResourcesCfg;
};
#endif // TESTOGRE_H
TestOgre.cpp
#include "TestOgre.h"TestOgre::TestOgre(QWidget *parent):QWidget(parent){m_Root = 0;m_SceneManager = 0;m_RenderWindow = 0;m_Viewport = 0;m_Camera = 0;mPluginsCfg = Ogre::BLANK;mResourcesCfg = Ogre::BLANK;setAttribute(Qt::WA_OpaquePaintEvent);setAttribute(Qt::WA_PaintOnScreen);setFocusPolicy(Qt::ClickFocus);}TestOgre::~TestOgre(){if(m_RenderWindow){
m_RenderWindow->removeAllViewports();}
if(m_Root){
m_Root->detachRenderTarget(m_RenderWindow);if(m_SceneManager){
m_Root->destroySceneManager(m_SceneManager);}
}
delete m_Root;}QPaintEngine* TestOgre::paintEngine() const{return NULL;}void TestOgre::paintEvent(QPaintEvent *e){m_Root->_fireFrameStarted();m_RenderWindow->update();m_Root->_fireFrameEnded();e->accept();
}void TestOgre::resizeEvent(QResizeEvent *e){QWidget::resizeEvent(e);if(e->isAccepted()){
const QSize &newSize = e->size();if(m_RenderWindow){
m_RenderWindow->resize(newSize.width(), newSize.height());m_RenderWindow->windowMovedOrResized();}
if(m_Camera){
Ogre::Real aspectRatio = Ogre::Real(newSize.width()) / Ogre::Real(newSize.height());m_Camera->setAspectRatio(aspectRatio);}
}
}void TestOgre::showEvent(QShowEvent *e){if(!m_Root){
InitOgreSystem();
}
QWidget::showEvent(e);}void TestOgre::InitOgreSystem(){
SetupAndLoadResources();
Ogre::RenderSystem *renderSystem = m_Root->getRenderSystemByName("OpenGL Rendering Subsystem");m_Root->setRenderSystem(renderSystem);m_Root->initialise(false);Ogre::String widgetHandle;#ifdef Q_WS_WINwidgetHandle = Ogre::StringConverter::toString((size_t)((HWND)winId()));#else
QWidget *q_parent = dynamic_cast <QWidget *> (parent());QX11Info xInfo = x11Info();widgetHandle = Ogre::StringConverter::toString ((unsigned long)xInfo.display()) +":" + Ogre::StringConverter::toString ((unsigned int)xInfo.screen()) +":" + Ogre::StringConverter::toString ((unsigned long)q_parent->winId());#endif
Ogre::NameValuePairList misc;misc["externalWindowHandle"] = widgetHandle;m_RenderWindow = m_Root->createRenderWindow("Ogre rendering window",width(), height(), false, &misc);// Set default mipmap level (note: some APIs ignore this)Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);// initialise all resource groupsOgre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();// Create the SceneManager, in this case a generic onem_SceneManager = m_Root->createSceneManager(Ogre::ST_GENERIC);// Create the cameram_Camera = m_SceneManager->createCamera("myCamera");// Position it at 80 in Z directionm_Camera->setPosition(Ogre::Vector3(0,0,80));// Look back along -Zm_Camera->lookAt(Ogre::Vector3(0,0,-300));m_Camera->setNearClipDistance(5);// Create one viewport, entire windowm_Viewport = m_RenderWindow->addViewport(m_Camera);m_Viewport->setBackgroundColour(Ogre::ColourValue(0,0,0));// Alter the camera aspect ratio to match the viewportm_Camera->setAspectRatio(Ogre::Real(width()) / Ogre::Real(height()));CreateScene();
}void TestOgre::SetupAndLoadResources(){#ifdef _DEBUGmResourcesCfg = "resources_d.cfg";mPluginsCfg = "plugins_d.cfg";#else
mResourcesCfg = "resources.cfg";mPluginsCfg = "plugins.cfg";#endif
// set up resources// Load resource paths from config fileOgre::ConfigFile cf;cf.load(mResourcesCfg);m_Root = new Ogre::Root(mPluginsCfg);// Go through all sections & settings in the fileOgre::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);}
}
}void TestOgre::CreateScene(){Ogre::Entity* ogreHead = m_SceneManager->createEntity("Head", "ogrehead.mesh");Ogre::SceneNode* headNode = m_SceneManager->getRootSceneNode()->createChildSceneNode();headNode->attachObject(ogreHead);// Set ambient lightm_SceneManager->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));// Create a lightOgre::Light* l = m_SceneManager->createLight("MainLight");l->setPosition(20,80,50);}
3、在MainWindow类中声明一个TestOgre类指针,用以渲染主窗口的Widget
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "TestOgre.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
TestOgre* ogreWidget;
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ogreWidget = new TestOgre;
setCentralWidget(ogreWidget);
}
MainWindow::~MainWindow()
{
delete ui;
}
编译运行即可看到Ogre!
哈哈,这样以后就可以更进一步的学习Ogre了。下一步打算,添加帧监听器,加载地形,通过COM组件来调用Ogre。继续加油吧!
- OGRE与Qt的结合(一)----使用OGRE渲染QWidget
- Ogre 渲染队列(一)
- 简要分析ogre渲染队列的实现原理(一)
- Ogre的渲染优化心得(一) -- 前言
- OGRE 本地渲染引擎 与 C++/CLI 托管代码的混合编程(一)
- ogre与mfc结合
- ogre与CEGUI结合
- Ogre的渲染系统
- ogre的主要渲染流程(转)
- Ogre窗口嵌入QWidget
- ogre的主要渲染流程
- ogre的主要渲染流程
- ogre的主要渲染流程
- Ogre Mesh的渲染流程
- [转]OGRE的渲染流程
- Ogre的渲染优化心得
- Ogre的渲染优化心得
- ogre的主要渲染流程
- 状态模式state(对像行为)
- Servlet工作原理解析
- 二进制翻转
- Android全屏的时候floatmenu依然被任务栏的位置截掉一半setSystemUiVisibility()
- 工作总结第十六天
- OGRE与Qt的结合(一)----使用OGRE渲染QWidget
- 25 个超棒的 HTML5 & JavaScript 游戏引擎开发库
- Spring_aop配置
- 生活感悟
- Ubuntu 13.04 安装 OpenGL
- Tap titans乐趣
- (转)SQL 优化原则
- winsock2 图片传输
- 从5个人中选取2个人作为礼仪