查看完整版本: [-- Qt 整合 Irrlicht --]

QTCN开发网 -> Qt代码秀 -> Qt 整合 Irrlicht [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

kimtaikee 2013-09-07 13:25

Qt 整合 Irrlicht

1.从OGRE接过来的单例模板

template <typename T> class Singleton {
private:
    /** \brief Explicit private copy constructor. This is a forbidden operation.*/
    Singleton(const Singleton<T> &);
    /** \brief Private operator= . This is a forbidden operation. */
    Singleton& operator=(const Singleton<T> &);
protected:
    static T* ms_Singleton;
public:
    Singleton( void )
    {
        Q_ASSERT( !ms_Singleton );
#if defined( _MSC_VER ) && _MSC_VER < 1200
        int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
        ms_Singleton = (T*)((int)this + offset);
#else
        ms_Singleton = static_cast< T* >( this );
#endif
    }
    ~Singleton( void )
    { Q_ASSERT( ms_Singleton ); ms_Singleton = 0; }
    static T& getSingleton( void )
    { Q_ASSERT( ms_Singleton ); return ( *ms_Singleton ); }
    static T* getSingletonPtr( void )
    { return ms_Singleton; }
};

2. QIrrlicht.h 也是从网上多方面攒起来的。
原地址:
看不懂法语的就看代码吧
http://www.siteduzero.com/forum/sujet/qt-integration-de-irrlicht-70274
http://www.matrix44.net/blog/?p=389


#ifndef QIrrlicht_H
#define QIrrlicht_H


#include <QtWidgets/QWidget>
#include <QtWidgets/QPushButton>
#include <QtCore/QDebug>
#include <QResizeEvent>
#include <irrlicht.h>


#include "singleton.h"


using namespace irr;
using namespace irr::video;
using namespace irr::core;
using namespace irr::scene;
using namespace irr::io;


class QIrrlicht : public QWidget, public Singleton<QIrrlicht>
{
    Q_OBJECT
public:
    QIrrlicht();


    IrrlichtDevice* getDevice() const ;
    ISceneManager* getSceneManager() const;
    IVideoDriver* getVideoDriver() const;


    void setBackgroundColor(const QColor& clr);
    QColor getBackgroundColor() const;


protected:
    virtual void timerEvent(QTimerEvent *);
    virtual void paintEvent( QPaintEvent *event );
    virtual void resizeEvent( QResizeEvent *event );
    virtual void mousePressEvent(QMouseEvent *);
    virtual void mouseReleaseEvent(QMouseEvent *);
    virtual void wheelEvent(QWheelEvent *);
    virtual void keyPressEvent(QKeyEvent *);
    virtual void keyReleaseEvent(QKeyEvent *);
    virtual QPaintEngine * paintEngine() const;


private:
    void sendKeyEventToIrrlicht( QKeyEvent* event, bool pressedDown );
    void sendMouseEventToIrrlicht( QMouseEvent* event, bool pressedDown );
    void createIrrlichtDevice();
    void buildIrrlichtScene();
    void drawIrrlichtScene();


private:
    IrrlichtDevice* _device;
    ISceneManager* _sceneManager;
    IVideoDriver* _videoDriver;
    SColor _bgColor;
};


#endif // QIrrlicht_H

QIrrlicht.cpp


#include "QIrrlicht.h"


struct SIrrlichtKey
{
    irr::EKEY_CODE code;
    wchar_t ch;
};




SIrrlichtKey convertToIrrlichtKey( int key )
{
    SIrrlichtKey irrKey;
    irrKey.code = (irr::EKEY_CODE)(0);
    irrKey.ch = (wchar_t)(0);


    // Letters A..Z and numbers 0..9 are mapped directly
    if ( (key >= Qt::Key_A && key <= Qt::Key_Z) || (key >= Qt::Key_0 && key <= Qt::Key_9) )
    {
        irrKey.code = (irr::EKEY_CODE)( key );
        irrKey.ch = (wchar_t)( key );
    }
    else


        // Dang, map keys individually
#define MAP_QT_IRRLICHT_KEY(QT_KEY,IRRLICHT_KEY) \
                                                case QT_KEY: \
                                                    irrKey.code = IRRLICHT_KEY; \
                                                    break;


        switch( key )
        {
            MAP_QT_IRRLICHT_KEY(Qt::Key_Escape, irr::KEY_ESCAPE)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Tab, irr::KEY_TAB)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Back, irr::KEY_BACK)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Return, irr::KEY_RETURN)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Enter, irr::KEY_RETURN)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Insert, irr::KEY_INSERT)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Delete, irr::KEY_DELETE)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Pause, irr::KEY_PAUSE)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Print, irr::KEY_PRINT)
//            MAP_QT_IRRLICHT_KEY(Qt::Key_SysReq, irr::KEY_S
            MAP_QT_IRRLICHT_KEY(Qt::Key_Clear, irr::KEY_CLEAR)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Home, irr::KEY_HOME)
            MAP_QT_IRRLICHT_KEY(Qt::Key_End, irr::KEY_END)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Left, irr::KEY_LEFT)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Up, irr::KEY_UP)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Right, irr::KEY_RIGHT)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Down, irr::KEY_DOWN)
            MAP_QT_IRRLICHT_KEY(Qt::Key_PageUp, irr::KEY_PRIOR)
            MAP_QT_IRRLICHT_KEY(Qt::Key_PageDown, irr::KEY_NEXT)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Shift, irr::KEY_SHIFT)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Control, irr::KEY_CONTROL)
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Meta, irr::KEY_ME
            MAP_QT_IRRLICHT_KEY(Qt::Key_Alt, irr::KEY_MENU)
            MAP_QT_IRRLICHT_KEY(Qt::Key_CapsLock, irr::KEY_CAPITAL)
            MAP_QT_IRRLICHT_KEY(Qt::Key_NumLock, irr::KEY_NUMLOCK)
            MAP_QT_IRRLICHT_KEY(Qt::Key_ScrollLock, irr::KEY_SCROLL)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F1, irr::KEY_F1)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F2, irr::KEY_F2)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F3, irr::KEY_F3)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F4, irr::KEY_F4)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F5, irr::KEY_F5)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F6, irr::KEY_F6)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F7, irr::KEY_F7)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F8, irr::KEY_F8)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F9, irr::KEY_F9)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F10, irr::KEY_F10)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F11, irr::KEY_F11)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F12, irr::KEY_F12)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F13, irr::KEY_F13)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F14, irr::KEY_F14)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F15, irr::KEY_F15)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F16, irr::KEY_F16)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F17, irr::KEY_F17)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F18, irr::KEY_F18)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F19, irr::KEY_F19)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F20, irr::KEY_F20)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F21, irr::KEY_F21)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F22, irr::KEY_F22)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F23, irr::KEY_F23)
            MAP_QT_IRRLICHT_KEY(Qt::Key_F24, irr::KEY_F24)
//            MAP_QT_IRRLICHT_KEY(Qt::Key_F25, irr::KEY_F
//            MAP_QT_IRRLICHT_KEY(Qt::Key_F26, irr::KEY_F
//            MAP_QT_IRRLICHT_KEY(Qt::Key_F27, irr::KEY_F
//            MAP_QT_IRRLICHT_KEY(Qt::Key_F28, irr::KEY_F
//            MAP_QT_IRRLICHT_KEY(Qt::Key_F29, irr::KEY_F
//            MAP_QT_IRRLICHT_KEY(Qt::Key_F30, irr::KEY_F
//            MAP_QT_IRRLICHT_KEY(Qt::Key_F31, irr::KEY_F
//            MAP_QT_IRRLICHT_KEY(Qt::Key_F32, irr::KEY_F
//            MAP_QT_IRRLICHT_KEY(Qt::Key_F33, irr::KEY_F
//            MAP_QT_IRRLICHT_KEY(Qt::Key_F34, irr::KEY_F
//            MAP_QT_IRRLICHT_KEY(Qt::Key_F35, irr::KEY_F
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Super_L, irr::KEY_SU
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Super_R
            MAP_QT_IRRLICHT_KEY(Qt::Key_Menu, irr::KEY_MENU)
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Hyper_L
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Hyper_R
            MAP_QT_IRRLICHT_KEY(Qt::Key_Help, irr::KEY_HELP)
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Direction_L
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Direction_R
            MAP_QT_IRRLICHT_KEY(Qt::Key_Space, irr::KEY_SPACE)
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Any, irr::KEY_SPACE)
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Exclam
//            MAP_QT_IRRLICHT_KEY(Qt::Key_QuoteDbl
//            MAP_QT_IRRLICHT_KEY(Qt::Key_NumberSign
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Dollar
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Percent
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Ampersand
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Apostrophe
//            MAP_QT_IRRLICHT_KEY(Qt::Key_ParenLeft
//            MAP_QT_IRRLICHT_KEY(Qt::Key_ParenRight
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Asterisk, irr::
            MAP_QT_IRRLICHT_KEY(Qt::Key_Plus, irr::KEY_PLUS)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Comma, irr::KEY_COMMA)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Minus, irr::KEY_MINUS)
            MAP_QT_IRRLICHT_KEY(Qt::Key_Period, irr::KEY_PERIOD)
//            MAP_QT_IRRLICHT_KEY(Qt::Key_Slash,irr::KEY_SEPARATOR)




        }
#undef MAP_QT_IRRLICHT_KEY
    return irrKey;
}




//////////////////////////////////////////////////
//////////////////////////////////////////////////
//////////////////////////////////////////////////
template <>
QIrrlicht* Singleton<QIrrlicht>::ms_Singleton = NULL;


QIrrlicht::QIrrlicht()
{
    setAttribute( Qt::WA_PaintOnScreen, true );
    setAutoFillBackground(true);
    createIrrlichtDevice();
    startTimer(0);
}


void QIrrlicht::sendKeyEventToIrrlicht( QKeyEvent* event, bool pressedDown )
{
    irr::SEvent irrEvent;


    irrEvent.EventType = irr::EET_KEY_INPUT_EVENT;


    SIrrlichtKey irrKey = convertToIrrlichtKey( event->key() );


    if ( irrKey.code == 0 ) return; // Could not find a match for this key


    irrEvent.KeyInput.Key = irrKey.code;
    irrEvent.KeyInput.Control = ((event->modifiers() & Qt::ControlModifier) != 0);
    irrEvent.KeyInput.Shift = ((event->modifiers() & Qt::ShiftModifier) != 0);
    irrEvent.KeyInput.Char = irrKey.ch;
    irrEvent.KeyInput.PressedDown = pressedDown;


    _device->postEventFromUser( irrEvent );
}


void QIrrlicht::sendMouseEventToIrrlicht( QMouseEvent* event, bool pressedDown )
{
    irr::SEvent irrEvent;


    irrEvent.EventType = irr::EET_MOUSE_INPUT_EVENT;


    switch ( event->button() )
    {
    case Qt::LeftButton:
        irrEvent.MouseInput.Event = pressedDown? irr::EMIE_LMOUSE_PRESSED_DOWN:irr::EMIE_LMOUSE_LEFT_UP;
        break;


    case Qt::MidButton:
        irrEvent.MouseInput.Event = pressedDown? irr::EMIE_MMOUSE_PRESSED_DOWN:irr::EMIE_MMOUSE_LEFT_UP;
        break;


    case Qt::RightButton:
        irrEvent.MouseInput.Event = pressedDown? irr::EMIE_RMOUSE_PRESSED_DOWN:irr::EMIE_RMOUSE_LEFT_UP;
        break;


    default:
        return; // Cannot handle this mouse event
    }


    irrEvent.MouseInput.X = event->x();
    irrEvent.MouseInput.Y = event->y();
    irrEvent.MouseInput.Wheel = 0.0f; // Zero is better than undefined


    _device->postEventFromUser( irrEvent );
}


void QIrrlicht::createIrrlichtDevice()
{
    dimension2d<u32> windowSize( this->geometry().width(), this->geometry().height() );


    qDebug() << "QIrrlicht::createIrrlichtDevice, width = " << windowSize.Width << " height = " << windowSize.Height;


    SIrrlichtCreationParameters createParams;
    createParams.WindowId = ( void * ) this->winId();
    createParams.AntiAlias = 1;
    createParams.DriverType = EDT_OPENGL;
    createParams.Bits = 16;
    createParams.DriverMultithreaded = true;
    createParams.IgnoreInput = false;
    createParams.HighPrecisionFPU = true;
    createParams.Vsync = false;
    createParams.Stencilbuffer = false;
    _device = createDeviceEx( createParams );
    if( _device == 0 )
        qDebug() << "failed to create irrlicht device";


    _device->setResizable(true);
    _videoDriver = _device->getVideoDriver();
    _sceneManager = _device->getSceneManager();


    buildIrrlichtScene();
}


void QIrrlicht::buildIrrlichtScene()
{
    IAnimatedMesh* mesh = _sceneManager->getMesh("../media/sydney.md2");
    _sceneManager->loadScene("../media/example.irr");
    _sceneManager->addCameraSceneNode(0, vector3df(0, 30, -40), vector3df(0, 5, 0));
    IAnimatedMeshSceneNode* node = _sceneManager->addAnimatedMeshSceneNode(mesh);
    if(node ) {
        node->setMaterialFlag(EMF_LIGHTING, false);
        node->setMaterialTexture(0, _videoDriver->getTexture("../media/sydney.bmp"));
        node->setPosition(vector3df(20,0,10));
        node->setScale(vector3df(0.5,0.5,0.5));
        node->setRotation(vector3df(0,90,0));
    }
}


void QIrrlicht::timerEvent( QTimerEvent* event )
{
    if ( _device != 0 )
    {
        update();
    }
}
void QIrrlicht::paintEvent( QPaintEvent *event )
{
    drawIrrlichtScene();
}


void QIrrlicht::resizeEvent( QResizeEvent *event )
{
    QWidget::resizeEvent(event);
    if ( _device != 0 )
    {
        irr::core::dimension2d<unsigned int> size;
        size.Width = event->size().width();
        size.Height = event->size().height();
        _videoDriver->OnResize( size );
    }
}
void QIrrlicht::mousePressEvent(QMouseEvent *event)
{
    if ( _device != 0 )
    {
        sendMouseEventToIrrlicht( event, true );
    }
    event->ignore();
}


void QIrrlicht::mouseReleaseEvent(QMouseEvent *event)
{
    if ( _device != 0 )
    {
        sendMouseEventToIrrlicht( event, false );
    }
    event->ignore();
}


void QIrrlicht::wheelEvent(QWheelEvent *event)
{
    if ( _device != 0 && event->orientation() == Qt::Vertical )
    {
        irr::SEvent irrEvent;


        irrEvent.EventType = irr::EET_MOUSE_INPUT_EVENT;


        irrEvent.MouseInput.Event = irr::EMIE_MOUSE_WHEEL;
        irrEvent.MouseInput.X = 0; // We don't know these,
        irrEvent.MouseInput.Y = 0; // but better zero them instead of letting them be undefined
        irrEvent.MouseInput.Wheel = event->delta() / 120.0f;


        _device->postEventFromUser( irrEvent );
    }
    event->ignore();
}


void QIrrlicht::keyPressEvent(QKeyEvent *event)
{
    if ( _device != 0 )
    {
        sendKeyEventToIrrlicht( event, true );
    }
    event->ignore();
}


void QIrrlicht::keyReleaseEvent(QKeyEvent *event)
{
    if ( _device != 0 )
    {
        sendKeyEventToIrrlicht( event, false );
    }
    event->ignore();
}


QPaintEngine * QIrrlicht::paintEngine() const
{
    return 0;
}


void QIrrlicht::drawIrrlichtScene()
{
    _device->getTimer()->tick();
    _videoDriver->beginScene( true, true, _bgColor);
    _sceneManager->drawAll();
    _videoDriver->endScene();
}


IrrlichtDevice* QIrrlicht::getDevice() const
{
    return _device;
}


ISceneManager* QIrrlicht::getSceneManager() const
{
    return _sceneManager;
}


IVideoDriver* QIrrlicht::getVideoDriver() const
{
    return _videoDriver;
}


void QIrrlicht::setBackgroundColor(const QColor &clr)
{
    _bgColor.setRed(clr.red());
    _bgColor.setGreen(clr.green());
    _bgColor.setBlue(clr.blue());
    _bgColor.setAlpha(clr.alpha());
    update();
}


QColor QIrrlicht::getBackgroundColor() const
{
    return QColor(_bgColor.getRed(), _bgColor.getGreen(), _bgColor.getBlue(), _bgColor.getAlpha());
}

程序入口点:


#include <QtWidgets/QApplication>


#include "QIrrlicht.h"


int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    QIrrlicht win;
    win.setWindowTitle(QObject::tr("Irrlicht Demo"));
    win.setBackgroundColor(QColor::fromRgb(0,170,150));
    win.show();
    return app.exec();
}



fkeujjpdc 2013-09-09 17:37
我想问问,如果我在QML界面中使用IRRLICHT要如何做啊

彩阳 2013-09-27 22:40
有人问,使用irrlicht渲染,加上Qt的GUI,这样可行吗?

kimtaikee 2013-09-29 21:26
这Demo不就说明了你的问题吗?


查看完整版本: [-- Qt 整合 Irrlicht --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled