Search code examples
c++qtqt3d

QText2DEntity Does not Render


I have a couple of questions, all surrounding the QText2DItem and while I'm unable to get a MWE in the time that I have to perform this task, I'm hoping to hear some speculation on what could fix the issue.

I have a QWidget which houses a Qt3DExtras::Qt3DWindow. This window is constructed as such:

    m_view = new Qt3DExtras::Qt3DWindow();
    m_container = createWindowContainer(m_view, this);
    m_view->renderSettings()->pickingSettings()->setPickResultMode(Qt3DRender::QPickingSettings::NearestPriorityPick);
    m_view->renderSettings()->pickingSettings()->setPickMethod(Qt3DRender::QPickingSettings::BoundingVolumePicking);
    m_view->renderSettings()->setRenderPolicy(Qt3DRender::QRenderSettings::OnDemand);
    m_view->defaultFrameGraph()->setFrustumCullingEnabled(false);

    m_camera = m_view->camera();
    m_scene = new Qt3DCore::QEntity();

    configure_scene();

    m_view->setRootEntity(m_scene);

Where configure_scene is:

    m_light_entity  = new Qt3DCore::QEntity(m_scene);
    m_light   = new Qt3DRender::QPointLight(m_light_entity);
    m_ltransform = new Qt3DCore::QTransform(m_scene);
    m_ltransform->setTranslation(QVector3D(0.1,10,0));
    m_light->setColor("white");
    m_light->setIntensity(0.8);
    m_light->setEnabled(true);
    m_light_entity->addComponent(m_light);
    m_light_entity->addComponent(m_ltransform);

    constexpr float cam_size = 1000.0f;

    m_camera->lens()->setPerspectiveProjection(10.0f, 16.0f/9.0f, 0.1f, cam_size);
    m_camera->setPosition(QVector3D(0.1f, 10.0f, 0.1f));
    m_camera->setViewCenter(QVector3D(0, 0, 0));

    QObject::connect( m_camera, &Qt3DRender::QCamera::viewCenterChanged, m_camera,
             [&](const QVector3D&){m_camera->setViewCenter(QVector3D(0,0,0));});

    QObject::connect( m_camera, &Qt3DRender::QCamera::positionChanged, m_camera,
                      [&](const QVector3D& v){if(v.y() <1){m_camera->setPosition({v.x(), 1, v.z()});};});

    AxisRender::draw_axes(m_scene, true, true, false);

    m_cam_controller = new Qt3DExtras::QOrbitCameraController(m_camera);
    m_cam_controller->setLinearSpeed( 50.0f );
    m_cam_controller->setLookSpeed( 180.0f );
    m_cam_controller->setCamera(m_camera);

There are several Qt3DCore::QEntitys created on the fly and added to the scene once the scene is constructed. At some point in the program, the entities may need to change or be removed entirely. Each Entity has a label assigned to it. The label is a QText2DEntity. The label and entities undergo several rotations to place them in the scene, with the scene as the root entity.

At some point in the program, I want to start this window from scratch. So, I remove the Widget which is constructed with the aforementioned functions from the UI, and create a new widget. This widget undergoes precisely the same initialization as it had when the program first started, except now the labels (QText2DEntitys) won't render. I have verified that they are constructed (as they have non-zero addresses), but they don't show in the scene.

Usually I would suspect that this has something to do with the way I'm handling objects, but the scene is effectively restored from scratch. The entities to which the labels belong are rendered in their correct locations, but the labels themselves are no where to be found. I have to restart the program to restore the labels.

What's even more confounding is that this doesn't happen every time. Sometimes the labels are shown when the m_view is deleted and regenerated.

That's the first and most pressing issue. The second issue is that the QText2DEntity backgrounds are not transparent. Sometimes the entities have white backgrounds, other times they appear clear from certain angles but have backgrounds from other angles. I've looked at this answer: Text2DEntity renders opaque and hides other entities behind it But this deals entirely with QML (my code is all C++) and some of the structures appear to be organized slightly differently. Also, the documentation for the QFordwardRenderer has left me wanting.


Solution

  • Unfortunately you hit bug QTBUG-77139 that hasn't been fixed for nearly 4 years. When constructing a QText2DEntity you would normally create it by passing a parent entity to it as follows:

    auto parent = new QEntity;
    auto text = new QText2DEntity(parent);
    

    As long as the scene is created the first time this works. But if you destroy the scene and reconstruct the entities the 2D-Text may not be displayed anymore.

    QTBUG-77139 describes a workaround to first construct the QText2DEntity and later explicitely call the setParent method as follow:

    auto parent = new QEntity;
    auto text = new QText2DEntity;
    text->setParent(parent);