PDA

View Full Version : Irrlicht in qt



shawk
14th August 2012, 22:39
does anyone know if you can port irrlicht engine to qt so it would be cross platfrom

ChrisW67
15th August 2012, 00:28
Irrlicht is already cross-platform C++.

shawk
15th August 2012, 01:34
So how do you get it working with qt

ChrisW67
15th August 2012, 02:33
Compile Irrlicht and link it to your application. This is only related to Qt if you use qmake to build your project (See Declaring Other Libraries), otherwise it is between you and your C++ compiler.

shawk
15th August 2012, 13:23
Does it need to be compile into lib to be cross platform

Donald Duck
21st January 2017, 19:11
This class creates a Qt widget with Irrlicht:



#include <QWidget>
#include <QTimer>
#include <QKeyEvent>
#include <irrlicht.h>

class IrrlichtWidget : public QWidget{
Q_OBJECT

public:
IrrlichtWidget(irr::u32 width = 600, irr::u32 height = 400){
setFixedSize(width, height);

irr::SIrrlichtCreationParameters params;
params.DriverType = irr::video::EDT_OPENGL;
params.WindowId = (void*)winId();
params.WindowSize.Width = width;
params.WindowSize.Height = height;
m_device = irr::createDeviceEx(params);

setAttribute(Qt::WA_OpaquePaintEvent);

m_timer = new QTimer;
m_timer->setInterval(0);
QObject::connect(m_timer, &QTimer::timeout, [this](){
emit inIrrlichtMainLoop();
m_device->run();
});
m_timer->start();
}

irr::IrrlichtDevice *getIrrlichtDevice() const{
return m_device;
}

signals:
void inIrrlichtMainLoop();

protected:
void keyPressEvent(QKeyEvent *event){
irr::SEvent irrEvent;
irrEvent.EventType = irr::EET_KEY_INPUT_EVENT;
IrrlichtKey irrKey;
irrKey.code = (irr::EKEY_CODE)(0);
irrKey.ch = (wchar_t)(0);
if((event->key() >= Qt::Key_A && event->key() <= Qt::Key_Z) || (event->key() >= Qt::Key_0 && event->key() <= Qt::Key_9)){
irrKey.code = (irr::EKEY_CODE)event->key();
irrKey.ch = (wchar_t)event->key();
}
else{
switch(event->key()){
case Qt::Key_Up:
irrKey.code = irr::KEY_UP;
break;

case Qt::Key_Down:
irrKey.code = irr::KEY_DOWN;
break;

case Qt::Key_Left:
irrKey.code = irr::KEY_LEFT;
break;

case Qt::Key_Right:
irrKey.code = irr::KEY_RIGHT;
break;
}
}
if(irrKey.code != 0){
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 = true;

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

void keyReleaseEvent(QKeyEvent *event){
irr::SEvent irrEvent;
irrEvent.EventType = irr::EET_KEY_INPUT_EVENT;
IrrlichtKey irrKey;
irrKey.code = (irr::EKEY_CODE)(0);
irrKey.ch = (wchar_t)(0);
if((event->key() >= Qt::Key_A && event->key() <= Qt::Key_Z) || (event->key() >= Qt::Key_0 && event->key() <= Qt::Key_9)){
irrKey.code = (irr::EKEY_CODE)event->key();
irrKey.ch = (wchar_t)event->key();
}
else{
switch(event->key()){
case Qt::Key_Up:
irrKey.code = irr::KEY_UP;
break;

case Qt::Key_Down:
irrKey.code = irr::KEY_DOWN;
break;

case Qt::Key_Left:
irrKey.code = irr::KEY_LEFT;
break;

case Qt::Key_Right:
irrKey.code = irr::KEY_RIGHT;
break;
}
}
if(irrKey.code != 0){
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 = false;

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

void mousePressEvent(QMouseEvent *event){
irr::SEvent irrEvent;

irrEvent.EventType = irr::EET_MOUSE_INPUT_EVENT;

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

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

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

default:
return;
}

irrEvent.MouseInput.X = event->x();
irrEvent.MouseInput.Y = event->y();
irrEvent.MouseInput.Wheel = 0.0f;

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

void mouseReleaseEvent(QMouseEvent* event){
irr::SEvent irrEvent;

irrEvent.EventType = irr::EET_MOUSE_INPUT_EVENT;

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

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

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

default:
return;
}

irrEvent.MouseInput.X = event->x();
irrEvent.MouseInput.Y = event->y();
irrEvent.MouseInput.Wheel = 0.0f;

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

void wheelEvent(QWheelEvent* event){
if(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;
irrEvent.MouseInput.Y = 0;
irrEvent.MouseInput.Wheel = event->delta() / 120.0f;

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


private:
struct IrrlichtKey{
irr::EKEY_CODE code;
wchar_t ch;
};

irr::IrrlichtDevice *m_device;
QTimer *m_timer;
};


To use this, instead of declaring the Irrlicht device using its constructor, use IrrlichtWidget's getIrrlichtDevice() method. For Irrlicht's main loop, don't create a while loop but use IrrlichtWidget's inIrrlichtMainLoop signal, which is emitted every time it's in the Irrlicht main loop. Here is an example:



IrrlichtWidget *myWidget = new IrrlichtWidget;
QObject::connect(myWidget, &IrrlichtWidget::inIrrlichtMainLoop, [myWidget](){
myWidget->getIrrlichtDevice()->getVideoDriver()->beginScene(true, true, irr::video::SColor(255, 255, 255, 255));
myWidget->getIrrlichtDevice()->getSceneManager()->drawAll();
myWidget->getIrrlichtDevice()->getVideoDriver()->endScene();
});


You don't need to call the device's run() method since it's called automatically.

To use Irrlicht in Qt Creator, you will have to add these two lines to the .pro file:



INCLUDEPATH += "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Libraries\\irrlicht-1.8.4\\include"
LIBS += -L"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Libraries\\irrlicht-1.8.4\\lib\\Win32-visualstudio" -lIrrlicht


Replace C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Libraries\\irrlicht-1.8.4 with the path in which you installed Irrlicht.

d_stranz
22nd January 2017, 22:32
shawk has been waiting 4 1/2 years for this answer. Now he can finally get on with his project...

xcxl
10th June 2018, 16:53
Hi,
thank you a lot Donald Duck, that works very well, it is a good start point for my project.
However I don't understand the lines :

QObject::connect(myWidget, &IrrlichtWidget::inIrrlichtMainLoop, [myWidget](){
myWidget->getIrrlichtDevice()->getVideoDriver()->beginScene(true, true, irr::video::SColor(255, 255, 255, 255));
myWidget->getIrrlichtDevice()->getSceneManager()->drawAll();
myWidget->getIrrlichtDevice()->getVideoDriver()->endScene();
});
I have never seen the "[]" bracket around a member, and I don't see the SLOT() like in "send, SIGNAL(), receiver, SLOT()" typical connection.

Anyone could explain me the " [myWidget](){...}"?

d_stranz
10th June 2018, 19:28
Go look up "C++ lambda expression" in your C++ book or online. And read the Qt 5 documentation for QObject::connect().