Qt3D QtQuick Scene2D 使用 C++

Posted

技术标签:

【中文标题】Qt3D QtQuick Scene2D 使用 C++【英文标题】:Qt3D QtQuick Scene2D using C++ 【发布时间】:2017-10-19 00:32:44 【问题描述】:

我正在尝试在 Scene3D 场景中的长方体或平面上渲染 QML 组件。我已经成功地遵循了文档中的示例,但我正在尝试将其转换为 C++ API,因为我需要做的还有更多,只有 C++ 就足够了。这是我的类的 ctor,它根据示例代码设置实体及其组件。为简洁起见,我只包括 ctor。课堂上没有其他任何东西会影响这一点。

ESEctoPointToast::ESEctoPointToast(Qt3DCore::QNode *parent)
:   Qt3DCore::QEntity(parent)
,   m_position(QVector3D(0,0,0))
,   m_quickItem(nullptr)
,   m_cuboid(new Qt3DExtras::QCuboidMesh())
,   m_textureMaterial(new Qt3DExtras::QTextureMaterial())
,   m_transform(new Qt3DCore::QTransform())
,   m_objectPicker(new Qt3DRender::QObjectPicker())
,   m_texture2d(new Qt3DRender::QTexture2D())
,   m_renderTargetOutput(new Qt3DRender::QRenderTargetOutput())
,   m_scene2d(new Qt3DRender::Quick::QScene2D())

    // g_RootQmlObject is the root item in the main scene, this was the only
    // way I could come up with to access qmlEngine. Is there a better way?
    auto engine = qmlEngine(g_RootQmlObject);
    QQmlComponent c(engine, QUrl("qrc:/components/E3DDummy.qml"));
    m_quickItem = qobject_cast<QQuickItem*>(c.create());
    Q_ASSERT(m_quickItem);

    m_texture2d->setWidth(256);
    m_texture2d->setHeight(256);
    m_texture2d->setFormat(Qt3DRender::QAbstractTexture::TextureFormat::RGB8_UNorm);
    m_texture2d->setGenerateMipMaps(true);
    m_texture2d->setMagnificationFilter(Qt3DRender::QAbstractTexture::Filter::Linear);
    m_texture2d->setMinificationFilter(Qt3DRender::QAbstractTexture::Filter::LinearMipMapLinear);
    m_texture2d->setWrapMode(Qt3DRender::QTextureWrapMode(Qt3DRender::QTextureWrapMode::ClampToEdge));
    m_renderTargetOutput->setAttachmentPoint(Qt3DRender::QRenderTargetOutput::AttachmentPoint::Color0);
    m_renderTargetOutput->setTexture(m_texture2d);
    m_textureMaterial->setTexture(m_texture2d);
    m_scene2d->setItem(m_quickItem);
    m_scene2d->setMouseEnabled(true);
    m_scene2d->setRenderPolicy(Qt3DRender::Quick::QScene2D::RenderPolicy::Continuous);
    m_scene2d->setOutput(m_renderTargetOutput);
    m_scene2d->addEntity(this);

    addComponent(m_transform);
    addComponent(m_textureMaterial);
    addComponent(m_cuboid);
    addComponent(m_objectPicker);

我将它从另一个类中包含在我的 Scene3D 中,在该类中它呈现为一个黑框,上面挤着无意义的红色文本。显然这是不对的。我哪里出错了?

这是渲染的:

【问题讨论】:

g_RootQmlObject 是现有的、正在运行的 QQmlEngine 的一部分吗?如果没有,您可能需要启动一个新的 QQmlEngine。请参阅此处“详细说明”下的示例:doc.qt.io/qt-5/qqmlengine.html 是的,g_RootQmlObject 正在运行。不过我会尝试启动一个新的 QQmlEngine 以防万一。 不幸的是,没有。创建一个新的 QQmlEngine 产生相同的结果。 随机纹理可能是刚刚留在 GPU 内存中的其他一些数据。我不知道为什么在您的情况下它会失败,但这通常是目标纹理或渲染目标输出中某些错误设置的症状。我会仔细检查 QML 示例中设置的所有属性,并验证您在 C++ 代码中所做的完全相同。 更新到 5.9.2 现在看来我已经触发了bugreports.qt.io/browse/QTBUG-60974 【参考方案1】:

这是由 Qt 5.9.x 中存在的错误引起的。 https://bugreports.qt.io/browse/QTBUG-60974 目前没有可行的解决方案。显然,在平面上渲染 QML 在 5.9.x 中被破坏了。

更新:QT 报告该错误在 5.11.1 中不再存在。 https://bugreports.qt.io/browse/QTBUG-60974?focusedCommentId=409471&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-409471

【讨论】:

以上是关于Qt3D QtQuick Scene2D 使用 C++的主要内容,如果未能解决你的问题,请参考以下文章

C ++中的Qt3d输入

Qt3d用c ++输入

将 Qt3D 用于巨大的地形模型?

如何使用libGDX更改Scene2D图像中的纹理?

基于QtQuick的QCustomPlot实现

将 scene2d.ui 与 libgdx 一起使用:皮肤从何而来?