3

I just recently started to use QT3D for a sideproject at work. And i'm surprised how fast you get something that looks pretty decent (at least for my case).

But i still have an issue with rendering speed and CPU usage. I've written a small test program to showcase this (see below). As we use Ubuntu i though it may be an issue with the NVIDIA driver but i tested it at home on my Windows PC as well.

And had the same results:

  • CPU usage is very high - 100% on one Core all the time.
  • GPU usage show no real difference if the application is running or not.

So my best guess is that it uses software rendering instead of the hardware? Any ideas?

The example just draws 2000 Cuboids with random sizes on random positions with a light source above.

#include <QGuiApplication>
#include <QRandomGenerator>
#include <QHBoxLayout>

#include <Qt3DRender/QCamera>
#include <Qt3DCore/QEntity>

#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtGui/QScreen>

#include <Qt3DCore/QTransform>
#include <Qt3DCore/QAspectEngine>

#include <Qt3DExtras/QForwardRenderer>
#include <Qt3DRender/QPointLight>
#include <Qt3DExtras/QCuboidMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>

#include <Qt3DExtras/Qt3DWindow>
#include <Qt3DExtras/QOrbitCameraController>

int main(int argc, char **argv)
{
    //basic window/widget stuff
    QApplication app(argc, argv);
    Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow();
    view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x4d4d4f)));
    QWidget *container = QWidget::createWindowContainer(view);
    QSize screenSize = view->screen()->size();
    container->setMinimumSize(QSize(200, 100));
    container->setMaximumSize(screenSize);
    QWidget *widget = new QWidget;
    QHBoxLayout *hLayout = new QHBoxLayout(widget);
    hLayout->addWidget(container, 1);

    //root entity
    Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
    view->setRootEntity(rootEntity);

    //setup camera
    view->camera()->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 10.0f, 5000.0f);
    view->camera()->setPosition(QVector3D(0, 0, 3000));
    view->camera()->setUpVector(QVector3D(0, 1, 0));
    view->camera()->setViewCenter(QVector3D(0, 0, 0));

    //orbit camera controller
    Qt3DExtras::QOrbitCameraController *camController = new Qt3DExtras::QOrbitCameraController(rootEntity);
    camController->setCamera(view->camera());
    camController->setLookSpeed(500);

    //add light
    Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(rootEntity);
    Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);
    light->setColor("white");
    light->setIntensity(1);
    lightEntity->addComponent(light);
    Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity);
    lightTransform->setTranslation(QVector3D(0, 5000, 0));
    lightEntity->addComponent(lightTransform);

    //add objects
    QRandomGenerator rng(1234);
    for(int i = 0; i <= 2000; i++)
    {
        Qt3DCore::QEntity* shapeEntity = new Qt3DCore::QEntity(rootEntity);
        Qt3DExtras::QCuboidMesh* mesh = new Qt3DExtras::QCuboidMesh();
        mesh->setXExtent(int(rng.generate() % 30)+20);
        mesh->setYExtent(int(rng.generate() % 30)+20);
        mesh->setZExtent(int(rng.generate() % 30)+20);
        shapeEntity->addComponent(mesh);
        Qt3DExtras::QDiffuseSpecularMaterial *material = new Qt3DExtras::QDiffuseSpecularMaterial();
        material->setAmbient(QColor(Qt::red).darker(150));
        material->setDiffuse(QColor(Qt::red));

        shapeEntity->addComponent(material);
        Qt3DCore::QTransform* pTrans = new Qt3DCore::QTransform();
        pTrans->setTranslation(QVector3D(int(rng.generate() % 2000)-1000, int(rng.generate() % 2000)-1000, int(rng.generate() % 2000)-1000));
        shapeEntity->addComponent(pTrans);
    }

    //show
    widget->show();
    widget->resize(1200, 800);

    return app.exec();
}
Der Ebly
  • 41
  • 4
  • You may need to add `auto renderSettings = view->renderSettings(); renderSettings->setRenderPolicy(Qt3DRender::QRenderSettings::OnDemand);` after creating your view to improve the CPU usage. – vre May 07 '20 at 11:31
  • Of course i tried that already. And yes it works if it is a still image as nothing needs to be rendered. But that doesn't solve the problem, does it? Something is always moving (not in the example but in an actual use case)... – Der Ebly May 07 '20 at 12:19
  • Did you already tried to use a more recent version, e.g. 5.14.2? Don't know if every improvement in later versions is ported back to the LTS version. – vre May 07 '20 at 12:29
  • Just downloaded 5.14.2 and tried with that version on Ubuntu (had no chance to try windows). But still the same :-/ – Der Ebly May 07 '20 at 12:48
  • This is basically to recommend: try this and that. This is not specific Qt version or Linux version to blame. But usually the quality of the OpenGL driver on specific hardware in Linux. Same issues also appear on Windows but usually can be fixed with tweaking it to use OpenGL ES 2 effectively using Direct X instead of Open GL directly. Do not forget about setRenderPolicy(). Also read on render loop: https://doc.qt.io/qt-5/qtquick-visualcanvas-scenegraph.html#threaded-render-loop-threaded and https://www.qt.io/blog/2017/01/18/opengl-implementation-qt-quick-app-using-today – Alexander V May 07 '20 at 14:23
  • Thanks for your answers but uhmm... I thought the Scenegraph can only handle 2D scenes? So as i'm using Qt3d those 2 documents don't really apply. Or am i mistaken here? – Der Ebly May 08 '20 at 06:57

0 Answers0