Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[Qt3D] Crash when deleting more than one Text2DEntity due to shared SpriteAtlas font (Qt 5.14)



  • Hello,
    I want to share with you a problem with the Qt3D part, and see if someone else encounter the same problem.
    For a project I managed to update my current version of Qt. I upgraded from Qt5.12 to Qt5.14. I use different Text2DEntity in a 3D scene and I experienced some crashes.

    After some research I was able to find the source of the problem. In fact the QText2DEntity seems to use a shared SpriteAtlas for the font. When the first QText2DEntity is deleted, the texture of the SpriteAtlas is deleted and when the second one is deleted, the destruction search to delete the same texture of the same SpriteAtlas producing a crash.

    You can reproduce the problem with this peace of code below, if you build it with Qt5.12 each Text2DEntity has his proper QFont, if you build it with Qt5.14, well you'll encounter my problem. (I didn't test with Qt5.13)

    main.cpp :

    #include <QGuiApplication>
    #include <Qt3DCore/QEntity>
    #include <Qt3DCore/QTransform>
    #include <Qt3DExtras/Qt3DWindow>
    #include <Qt3DExtras/QText2DEntity>
    #include <Qt3DRender/QCamera>
    #include <QTimer>
    
    #include <memory>
    
    int main(int argc, char *argv[])
    {
        QGuiApplication application(argc, argv);
        Qt3DExtras::Qt3DWindow window;
    
        QTimer timer1;
        timer1.setInterval(2000);
    
        QTimer timer2;
        timer2.setInterval(5000);
    
        Qt3DCore::QEntity scene(nullptr);
        window.setRootEntity(&scene);
    
        auto text2D1 = std::make_shared<Qt3DExtras::QText2DEntity>(&scene);
        text2D1->setFont(QFont("monospace",5));
        text2D1->setHeight(10.0);
        text2D1->setWidth(50.0);
        text2D1->setText("AAAAA");
        text2D1->setColor(Qt::black);
    
        auto text2dTransform1 = new Qt3DCore::QTransform;
        text2dTransform1->setTranslation(QVector3D(-10.0f, 0.0f, 50.0f));
        text2D1->addComponent(text2dTransform1);
    
        auto text2D2 = std::make_shared<Qt3DExtras::QText2DEntity>(&scene);
        text2D2->setFont(QFont("monospace",5));
        text2D2->setHeight(10.0);
        text2D2->setWidth(50.0);
        text2D2->setText("BBBBB");
        text2D2->setColor(Qt::black);
    
        auto text2dTransform2 = new Qt3DCore::QTransform;
        text2dTransform2->setTranslation(QVector3D(-10.0f, 6.0f, 50.0f));
        text2D2->addComponent(text2dTransform2);
    
        auto camera = window.camera();
        camera->lens()->setPerspectiveProjection(60.0f, static_cast<float>(window.width()) / window.height(), 0.1f, 1000.0f);
        camera->setPosition(QVector3D(0.0f, 0.0f, 100.0f));
        camera->setViewCenter(QVector3D(0.0f, 0.0f, 0.0f));
    
        window.show();
    
        QObject::connect(&timer1, &QTimer::timeout, [&text2D1](){if(text2D1) text2D1 = nullptr;});
        QObject::connect(&timer2, &QTimer::timeout, [&text2D2](){if(text2D2) text2D2 = nullptr;});
        timer1.start();
        timer2.start();
    
        return application.exec();
    }
    

    Test.pro :

    QT += quick 3dlogic 3dextras 3dinput
    
    CONFIG += c++14
    
    # The following define makes your compiler emit warnings if you use
    # any Qt feature that has been marked deprecated (the exact warnings
    # depend on your compiler). Refer to the documentation for the
    # deprecated API to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if it uses deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    SOURCES += \
            main.cpp
    
    RESOURCES += qml.qrc
    

    Thank you !


Log in to reply