Sur cette page

Graphique de scène - Vulkan sous QML

Montre comment effectuer un rendu directement avec Vulkan sous une scène Qt Quick.

Remarque : la compilation de cet exemple nécessite un SDK. Voir Intégration de Vulkan pour plus d'informations sur ce qu'il faut installer.

Vue d'ensemble

Cet exemple utilise les signaux QQuickWindow::beforeRendering() et QQuickWindow::beforeRenderPassRecording() pour dessiner un contenu Vulkan personnalisé sous une scène Qt Quick. QML est utilisé pour rendre une étiquette de texte au-dessus.

L'exemple est équivalent dans la plupart des cas aux exemples OpenGL sous QML, Direct3D 11 sous QML, et Metal sous QML, ils rendent tous le même contenu personnalisé, juste via des API natives différentes.

Les particularités de l'utilisation de QML seront couvertes dans cette documentation sans entrer dans les détails du rendu Vulkan personnalisé.

Affecter le rendu Vulkan à partir de QML

L'exemple montre comment utiliser les valeurs exposées à QML pour contrôler le rendu Vulkan.

Pour exposer la valeur seuil t à QML, dans la définition de VulkanSquircle, nous utilisons les macros Q_OBJECT, Q_PROPERTY et QML_ELEMENT comme suit :

class VulkanSquircle : public QQuickItem
{
    Q_OBJECT
    Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged)
    QML_ELEMENT

Nous continuons ensuite à déclarer des éléments publics et privés :

public:
    VulkanSquircle();

    qreal t() const { return m_t; }
    void setT(qreal t);

signals:
    void tChanged();

public slots:
    void sync();
    void cleanup();

private slots:
    void handleWindowChanged(QQuickWindow *win);

private:
    void releaseResources() override;

    qreal m_t = 0;
    SquircleRenderer *m_renderer = nullptr;

Puis, dans main.qml, nous animons la valeur seuil à l'aide d'une variable NumberAnimation.

    VulkanSquircle {
        SequentialAnimation on t {
            NumberAnimation { to: 1; duration: 2500; easing.type: Easing.InQuad }
            NumberAnimation { to: 0; duration: 2500; easing.type: Easing.OutQuad }
            loops: Animation.Infinite

La variable t est finalement utilisée par le programme shader SPIR-V qui dessine les écureuils.

Utilisation de signaux pour le rendu de contenu Vulkan personnalisé

Les signaux QQuickWindow::beforeRendering() et QQuickWindow::beforeRenderPassRecording() sont utilisés.

Le signal QQuickWindow::beforeRendering() est émis au début de chaque image, avant que le graphe de scène ne commence son rendu. Cela signifie que tous les appels de dessin Vulkan effectués en réponse à ce signal s'empilent sous les éléments Qt Quick. Il y a deux signaux car les commandes Vulkan personnalisées sont enregistrées dans le même tampon de commande que celui utilisé par le graphe de scène.

La fonction beforeRendering() seule n'est pas suffisante pour cela, car elle est émise au début de l'image, avant d'enregistrer le début d'une instance renderpass à l'aide de vkCmdBeginRenderPass.

La solution : en se connectant à beforeRenderPassRecording(), les commandes de l'application et l'échafaudage du graphe de scène se retrouveront dans le bon ordre.

La fonction sync() se charge de connecter les signaux :

void VulkanSquircle::sync()
{
    if (!m_renderer) {
        m_renderer = new SquircleRenderer;
        // Initializing resources is done before starting to record the
        // renderpass, regardless of wanting an underlay or overlay.
        connect(window(), &QQuickWindow::beforeRendering, m_renderer, &SquircleRenderer::frameStart, Qt::DirectConnection);
        // Here we want an underlay and therefore connect to
        // beforeRenderPassRecording. Changing to afterRenderPassRecording
        // would render the squircle on top (overlay).
        connect(window(), &QQuickWindow::beforeRenderPassRecording, m_renderer, &SquircleRenderer::mainPassRecordingStart, Qt::DirectConnection);
    }
    m_renderer->setViewportSize(window()->size() * window()->devicePixelRatio());
    m_renderer->setT(m_t);

Une autre façon de rendre du contenu Vulkan au-dessus de la scène Qt Quick est de se connecter aux signaux QQuickWindow::afterRendering() et QQuickWindow::afterRenderPassRecording().

Exemple de projet @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.