Irrlicht, Qt and Qt Creator [Qt5 compatible]

A forum to store posts deemed exceptionally wise and useful
Post Reply
AGameDev
Posts: 5
Joined: Tue Jan 06, 2015 5:15 pm

Irrlicht, Qt and Qt Creator [Qt5 compatible]

Post by AGameDev »

As announced here (http://irrlicht.sourceforge.net/forum/v ... 30#p291401), I've tried a different approach to integrate Irrlicht into Qt.

My Goal was to seperate the Irrlicht related code as far as possible into a sperate class (or classes).

However there is still a bug present. I dunno if this is a Irrlicht related bug. It seems that OnResize in IrrCoreRenderer::resizeIrrWidget isn't working properly if a software renderer is used. (BTW: The other approach as linked above, has the same issue with software renderer)

Hint:

Its still not possible to run multiple instances of Irrlicht in one software where all instances are using OpenGL! One instance can use OpenGL, but other instances have to use the Burningsvideo renderer for example.

First steps:

- Create a new QtWidget Project in Qt Creator.
- Place two Widgets into MainWindow in Qt Designer.
- Make sure that the two widgets are children of centralWidget.
- Name one Widget "irrRenderWidget0" and one Widget "irrRenderWidget1"

Paste the following Code into your newly created Project.

Code: Select all

 
//mainwindow.h
 
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include "irrcorerenderer.h"
 
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
 
    IrrCoreRenderer* irr0;
    IrrCoreRenderer* irr1;
 
private:
    Ui::MainWindow *ui;
    void initIrrInstance0(QWidget *irrRenderTarget);
    void initIrrInstance1(QWidget *irrRenderTarget);
 
protected:
    virtual void resizeEvent(QResizeEvent *event);
};
 
#endif // MAINWINDOW_H
 

Code: Select all

 
//irrcorerenderer.h
 
#ifndef IRRCORERENDER_H
#define IRRCORERENDER_H
 
#include <QObject>
#include <QWidget>
#include <irrlicht.h>
 
using namespace irr;
 
class IrrCoreRenderer : public QWidget
{
    Q_OBJECT
 
public:
    IrrCoreRenderer(QWidget *irrRenderTarget, bool softwareRenderer);
    ~IrrCoreRenderer();
    void init();
    void resizeIrrWidget(int x, int y, int newWidth, int newHeight);
 
private:
    QWidget *irrRenderTarget;
    video::E_DRIVER_TYPE rendererType;
 
protected:
    SIrrlichtCreationParameters params;
    IrrlichtDevice* device;
 
    virtual void timerEvent(QTimerEvent* event);
};
 
#endif // IRRCORERENDER_H
 

Code: Select all

 
//main.cpp
 
#include "mainwindow.h"
#include <QApplication>
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
 
    return a.exec();
}
 

Code: Select all

 
//mainwindow.cpp
 
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 
    //Init an Irrlicht instance and give it a target widget into where Irrlicht should show its output - here I named it "irrRenderWidget0" and "irrRenderWidget1".
    this->initIrrInstance0(ui->centralWidget->findChild<QWidget *>("irrRenderWidget0"));
    this->initIrrInstance1(ui->centralWidget->findChild<QWidget *>("irrRenderWidget1"));
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::initIrrInstance0(QWidget *irrRenderTarget)
{
    this->irr0 = new IrrCoreRenderer(irrRenderTarget, false);
 
    this->irr0->init();
}
 
void MainWindow::initIrrInstance1(QWidget *irrRenderTarget)
{
    this->irr1 = new IrrCoreRenderer(irrRenderTarget, true);
 
    this->irr1->init();
}
 
void MainWindow::resizeEvent(QResizeEvent *event)
{
   this->irr0->resizeIrrWidget(0, 0, this->size().width()/2, this->size().height());
   this->irr1->resizeIrrWidget(this->size().width()/2, 0, this->size().width()/2, this->size().height());
}
 

Code: Select all

 
//irrcorerenderer.cpp
 
#include "irrcorerenderer.h"
 
IrrCoreRenderer::IrrCoreRenderer(QWidget *irrRenderTarget, bool softwareRenderer)
{
    this->irrRenderTarget = irrRenderTarget;
 
    if(softwareRenderer)
    {
       this->rendererType = video::EDT_BURNINGSVIDEO;
    } else
    {
        this->rendererType = video::EDT_OPENGL;
    }
 
    //Set Parameters. Most important part here is: params.WindowId. This value sets the output destination of this Irrlicht instance.
    this->params.AntiAlias = 0;
    this->params.Bits = 32;
    this->params.DeviceType = EIDT_X11;
    this->params.Doublebuffer = true;
    this->params.DriverType = rendererType;
    this->params.EventReceiver = 0;
    this->params.Fullscreen = false;
    this->params.HighPrecisionFPU = false;
    this->params.IgnoreInput = false;
    this->params.LoggingLevel = ELL_INFORMATION;
    this->params.Stencilbuffer = true;
    this->params.Stereobuffer = false;
    this->params.Vsync = false;
    this->params.WindowId = reinterpret_cast<void*>(this->irrRenderTarget->winId());
    this->params.WindowSize.Width = this->irrRenderTarget->size().width();
    this->params.WindowSize.Height = this->irrRenderTarget->size().height();
    this->params.WithAlphaChannel = false;
    this->params.ZBufferBits = 16;
 
    this->device = createDeviceEx(this->params);
}
 
IrrCoreRenderer::~IrrCoreRenderer()
{
    this->device->drop();
}
 
void IrrCoreRenderer::init()
{
    if (this->device != 0)
    {
        scene::ISceneManager* smgr = this->device->getSceneManager();
 
        this->device->getFileSystem()->addFileArchive("media/map-20kdm2.pk3");
 
        scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");
        scene::ISceneNode* node = 0;
 
        if (mesh)
        {
            node = smgr->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);
        }
 
        if (node)
        {
            node->setPosition(core::vector3df(-1300, -144, -1299));
        }
 
        smgr->addCameraSceneNode();
 
        startTimer(0);
    }
}
 
void IrrCoreRenderer::timerEvent(QTimerEvent* event)
{
    if(this->device != 0)
    {
        this->device->getTimer()->tick();
 
        video::SColor color (255, 100, 100, 140);
 
        this->device->getVideoDriver()->beginScene(true, true, color);
        this->device->getSceneManager()->drawAll();
        this->device->getVideoDriver()->endScene();
    }
}
 
void IrrCoreRenderer::resizeIrrWidget(int x, int y, int newWidth, int newHeight)
{
    //Resize the render target widget which shows the Irrlicht output.
    this->irrRenderTarget->setGeometry(x, y, newWidth, newHeight);
 
    //Resize Irrlicht render output itself
    if(this->device != 0)
    {   
        core::dimension2d<u32> widgetSize;
        widgetSize.Width = newWidth;
        widgetSize.Height = newHeight;
 
        this->device->getVideoDriver()->OnResize(widgetSize);
 
        scene::ICameraSceneNode *cam = this->device->getSceneManager()->getActiveCamera();
        if (cam != 0)
        {
            cam->setAspectRatio((f32)widgetSize.Width / (f32)widgetSize.Height);
        }
    }
}
 
Have fun! If someone knows how to get rid of the bug, you're welcome! :)
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: Irrlicht, Qt and Qt Creator [Qt5 compatible]

Post by thanhle »

Hi mate,
Is this mean that this method doesn't need the paint event to be update? I try update my gui to this but the window doesn't show anything.
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: Irrlicht, Qt and Qt Creator [Qt5 compatible]

Post by thanhle »

Please ignore message above.
Got it to work.

There is one bug, if you use the default MainWindow. There will be an assertion bug caused by zero size or empty action menu.
Just add at least one action then its fixed.

Regards
thanh
AGameDev
Posts: 5
Joined: Tue Jan 06, 2015 5:15 pm

Re: Irrlicht, Qt and Qt Creator [Qt5 compatible]

Post by AGameDev »

Sorry, that I didn't see your post earlier.

You're welcome. Nice that it works for you.
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: Resizing bug in QMdiSubWindow interface.

Post by thanhle »

Resizing bug in QMdiSubWindow interface.

Hi mate there seems to be a bug when develop using MDI mode. I'm not sure whether it is irrlicht or Qt.

Basically if we resize the sub window larger than the initial size, it got clipped edges. If I maximize then restore window size. The clip disappear and display is correct once again. See picture.

Do you have any tip to fix it.

Image

Any way openGL driver still have bug that we can only open 1 window from device. DirectX and buring video driver can open many windows from one device.

Image

Thanks
thanh
AGameDev
Posts: 5
Joined: Tue Jan 06, 2015 5:15 pm

Re: Irrlicht, Qt and Qt Creator [Qt5 compatible]

Post by AGameDev »

Any way openGL driver still have bug that we can only open 1 window from device. DirectX and buring video driver can open many windows from one device.
As I said: :wink:
Hint:

Its still not possible to run multiple instances of Irrlicht in one software where all instances are using OpenGL! One instance can use OpenGL, but other instances have to use the Burningsvideo renderer for example.
Irrlicht isn't made to run in multiple instances. That is what I found out in this Forum. If this works with DirectX, great. It seems that it has something to do with creating proper OpenGL context.
Basically if we resize the sub window larger than the initial size, it got clipped edges. If I maximize then restore window size. The clip disappear and display is correct once again. See picture.
I use Linux and I don't have this bug. I guess that it could be an issue with Qt AutoFill. Try to add

Code: Select all

setAutoFillBackground(false)
to IrrCoreRenderer constructor. Do you mean with "sub window" creating multiple windows inside a MainWindow?
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: Irrlicht, Qt and Qt Creator [Qt5 compatible]

Post by thanhle »

Yes, I mean subwindows (QMdiSubWindow.)

setAutoFillBackground(false) doesn't seem to do its task.

I'll find out other hack.

Fixed it.

For QMdiSubWindow you have to place the below code at the end of the resize event.

QMdiSubWindow::resizeEvent(event);

Best Regards
thanh
netpipe
Posts: 670
Joined: Fri Jun 06, 2008 12:50 pm
Location: Edmonton, Alberta, Canada
Contact:

Re: Irrlicht, Qt and Qt Creator [Qt5 compatible]

Post by netpipe »

Live long and phosphor!
-- https://github.com/netpipe/Luna Game Engine Status 95%
Post Reply