2

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.

Alex Baum
  • 166
  • 9
  • 1
    How did you construct the Text2DEntities? Maybe [this open issue](https://bugreports.qt.io/browse/QTBUG-77139) applies to your scenario. – vre Jun 29 '23 at 20:00
  • 1
    @vre, the Text2DEntities were constructed the way that the issue says is problematic (passing the root note as parent). I will try the issue's workaround. Sadly, this issue is now 4 years old. – Alex Baum Jun 29 '23 at 23:25
  • I've been hit by this issue too in the past. Regarding the transparency issues you experienced the only solution is to use a custom framegraph that first draws the opaque entities then the transparent ones. – vre Jun 30 '23 at 05:31
  • Do you have an example of constructing the custom framegraph? The documentation in Qt is merely a conversational document with several examples in QML. – Alex Baum Jun 30 '23 at 15:53
  • 1
    I'll add some code next week. – vre Jun 30 '23 at 21:56
  • 1
    @AlexBaum please post an answer if your problem has been resolved, I've just been reading through your question only to find it has been fixed ;) You should also always open a second question if you have a second one and not just put two in one post. Regarding the transparency check this out: https://stackoverflow.com/questions/55001233/qt3d-draw-transparent-qspheremesh-over-triangles/55033342#55033342 – Florian Blume Jul 01 '23 at 07:34
  • @FlorianBlume, I was hoping I would invoke your presence with a question regarding Qt3D. From what I've seen you appear to be the authority on Qt3D. Where did you learn about all of this? From playing with the library? Towards your linked answer, that might work. I will have to mess around with it. Currently each object is constructed with its own label. So the order of adding them is Object->Label, Object->Label, etc... If order matters I may have to form some sort of manager that handles the order in which things are arranged – Alex Baum Jul 02 '23 at 16:27
  • @vre, can you add your comment as an answer so I can close this? Or would you rather I do this? – Alex Baum Jul 02 '23 at 16:30
  • 1
    Haha "authority on Qt3D" I feel flattered ;) I implemented [this tool](https://github.com/florianblume/6d-pat) for uni once and had to dig through Qt3D - endless sweat and tears if that answers your question. If the answer doesn't work feel free to open a new question - I don't fully understand what you mean by the order here (you can never rely on order of construction in Qt3D due to threadding etc.). It's nice of you to ask Vre if they want to post the answer since their comment resolved the issue. I'd wait for their answer. – Florian Blume Jul 03 '23 at 07:41
  • @FlorianBlume, when I say order here, say I have 400 objects that will be drawn on the screen. I have implemented an abstract base class which encapsulates some default behaviour for those objects. For instance: creation of an QPhongMaterial, definition of a mesh, etc... I also create a label for the object in the abstract base class. The derived objects are then free to define their location in the 3D space, along with such things as what the labels say, etc... So in this case, I am guaranteed order of creation, at least as far as single object/label pair is defined – Alex Baum Jul 05 '23 at 14:24
  • @FlorianBlume, I had a chance to review your documentation from your other answer, it turns out that the QSortPolicy business going back to front fixed the issue. Thank you for all of your help. I would like to propose that I open some other question that is better targeted at this exact issue, in C++. Currently, the closest question is this one: https://stackoverflow.com/questions/57627805/text2dentity-renders-opaque-and-hides-other-entities-behind-it which uses OpenGL directly (not what I'm doing here) and the question you pointed to, which is less generic. – Alex Baum Jul 05 '23 at 15:03

1 Answers1

2

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);
vre
  • 6,041
  • 1
  • 25
  • 39