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_WIN
    widgetHandle = 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 groups
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
    // Create the SceneManager, in this case a generic one
    m_SceneManager = m_Root->createSceneManager(Ogre::ST_GENERIC);
    // Create the camera
    m_Camera = m_SceneManager->createCamera("myCamera");
    // Position it at 80 in Z direction
    m_Camera->setPosition(Ogre::Vector3(0,0,80));
    // Look back along -Z
    m_Camera->lookAt(Ogre::Vector3(0,0,-300));
    m_Camera->setNearClipDistance(5);
    // Create one viewport, entire window
    m_Viewport = m_RenderWindow->addViewport(m_Camera);
    m_Viewport->setBackgroundColour(Ogre::ColourValue(0,0,0));
    // Alter the camera aspect ratio to match the viewport
    m_Camera->setAspectRatio(Ogre::Real(width()) / Ogre::Real(height()));
    CreateScene();
}
void TestOgre::SetupAndLoadResources()
{
#ifdef _DEBUG
    mResourcesCfg = "resources_d.cfg";
    mPluginsCfg = "plugins_d.cfg";
#else
    mResourcesCfg = "resources.cfg";
    mPluginsCfg = "plugins.cfg";
#endif
    // set up resources
    // Load resource paths from config file
    Ogre::ConfigFile cf;
    cf.load(mResourcesCfg);
    m_Root = new Ogre::Root(mPluginsCfg);
    // Go through all sections & settings in the file
    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);
        }
    }
}
void TestOgre::CreateScene()
{
    Ogre::Entity* ogreHead = m_SceneManager->createEntity("Head", "ogrehead.mesh");
    Ogre::SceneNode* headNode = m_SceneManager->getRootSceneNode()->createChildSceneNode();
    headNode->attachObject(ogreHead);
    // Set ambient light
    m_SceneManager->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));
    // Create a light
    Ogre::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。继续加油吧!



0 0
原创粉丝点击