QRhiWidget Class
La classe QRhiWidget est un widget pour le rendu de graphiques 3D via une API graphique accélérée, telle que Vulkan, Metal ou Direct 3D. Plus d'informations...
| En-tête : | #include <QRhiWidget> |
| CMake : | find_package(Qt6 REQUIRED COMPONENTS Widgets)target_link_libraries(mytarget PRIVATE Qt6::Widgets) |
| qmake : | QT += widgets |
| Depuis : | Qt 6.7 |
| Hérite : | QWidget |
Types publics
| enum class | Api { Null, OpenGL, Metal, Vulkan, Direct3D11, Direct3D12 } |
| enum class | TextureFormat { RGBA8, RGBA16F, RGBA32F, RGB10A2 } |
Propriétés
|
|
Fonctions publiques
| QRhiWidget(QWidget *parent = nullptr, Qt::WindowFlags f = {}) | |
| virtual | ~QRhiWidget() override |
| QRhiWidget::Api | api() const |
| QRhiWidget::TextureFormat | colorBufferFormat() const |
| QSize | fixedColorBufferSize() const |
| QImage | grabFramebuffer() const |
| bool | isDebugLayerEnabled() const |
| bool | isMirrorVerticallyEnabled() const |
| int | sampleCount() const |
| void | setApi(QRhiWidget::Api api) |
| void | setColorBufferFormat(QRhiWidget::TextureFormat format) |
| void | setDebugLayerEnabled(bool enable) |
| void | setFixedColorBufferSize(QSize pixelSize) |
| void | setFixedColorBufferSize(int w, int h) |
| void | setMirrorVertically(bool enabled) |
| void | setSampleCount(int samples) |
Signaux
| void | colorBufferFormatChanged(QRhiWidget::TextureFormat format) |
| void | fixedColorBufferSizeChanged(const QSize &pixelSize) |
| void | frameSubmitted() |
| void | mirrorVerticallyChanged(bool enabled) |
| void | renderFailed() |
| void | sampleCountChanged(int samples) |
Fonctions protégées
| QRhiTexture * | colorTexture() const |
| QRhiRenderBuffer * | depthStencilBuffer() const |
| virtual void | initialize(QRhiCommandBuffer *cb) |
| QRhiRenderBuffer * | msaaColorBuffer() const |
| virtual void | releaseResources() |
| virtual void | render(QRhiCommandBuffer *cb) |
| QRhiRenderTarget * | renderTarget() const |
| QRhiTexture * | resolveTexture() const |
| QRhi * | rhi() const |
| void | setAutoRenderTarget(bool enabled) |
Fonctions protégées réimplémentées
| virtual bool | event(QEvent *e) override |
| virtual void | paintEvent(QPaintEvent *e) override |
| virtual void | resizeEvent(QResizeEvent *e) override |
Description détaillée
QRhiWidget fournit une fonctionnalité permettant d'afficher le contenu 3D rendu par les API QRhi dans une application basée sur QWidget. À bien des égards, il s'agit de l'équivalent portable de QOpenGLWidget qui n'est pas lié à une seule API graphique 3D, mais qui peut fonctionner avec toutes les API prises en charge par QRhi (telles que Direct 3D 11/12, Vulkan, Metal et OpenGL).
QRhiWidget devrait être sous-classé. Pour effectuer un rendu dans la texture 2D qui est implicitement créée et gérée par le QRhiWidget, les sous-classes doivent réimplémenter les fonctions virtuelles initialize() et render().
La taille de la texture s'adapte par défaut à la taille du widget. Si vous préférez une taille fixe, définissez une taille fixe spécifiée en pixels en appelant setFixedColorBufferSize().
En plus de la texture servant de tampon de couleur, un tampon de profondeur/stencil et une cible de rendu liant ces deux éléments sont également maintenus implicitement.
Le site QRhi pour la fenêtre de premier niveau du widget est configuré pour utiliser un backend et une API graphique spécifiques à la plateforme par défaut : Metal sur macOS et iOS, Direct 3D 11 sur Windows, OpenGL sinon. Appelez setApi() pour remplacer cette configuration.
Remarque : une même fenêtre widget ne peut utiliser qu'un seul backend QRhi, et donc une seule API graphique 3D. Si deux widgets QRhiWidget ou QQuickWidget dans la hiérarchie des widgets de la fenêtre demandent des API différentes, seul l'un d'entre eux fonctionnera correctement.
Remarque : bien que QRhiWidget soit une API publique de Qt, la famille de classes QRhi du module Qt GUI, y compris QRhi, QShader et QShaderDescription, offre des garanties de compatibilité limitées. Il n'existe aucune garantie de compatibilité source ou binaire pour ces classes, ce qui signifie que l'API n'est garantie de fonctionner qu'avec la version de Qt avec laquelle l'application a été développée. Les changements incompatibles avec le code source doivent cependant être réduits au minimum et ne seront apportés que dans les versions mineures (6.7, 6.8, etc.). qrhiwidget.h n'inclut pas directement les en-têtes liés à QRhi. Pour utiliser ces classes lors de l'implémentation d'une sous-classe de QRhiWidget, il convient de créer un lien vers Qt::GuiPrivate (si vous utilisez CMake) et d'inclure les en-têtes appropriés avec le préfixe rhi, par exemple #include <rhi/qrhi.h>.
Voici un exemple de sous-classe de QRhiWidget simple qui rend un triangle :
class ExampleRhiWidget : public QRhiWidget { public: ExampleRhiWidget(QWidget *parent = nullptr) : QRhiWidget(parent) { } void initialize(QRhiCommandBuffer *cb) override; void render(QRhiCommandBuffer *cb) override; private: QRhi *m_rhi = nullptr; std::unique_ptr<QRhiBuffer> m_vbuf; std::unique_ptr<QRhiBuffer> m_ubuf; std::unique_ptr<QRhiShaderResourceBindings> m_srb; std::unique_ptr<QRhiGraphicsPipeline> m_pipeline; QMatrix4x4 m_viewProjection; float m_rotation = 0.0f; }; float vertexData[] = { 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, }; QShader getShader(const QString &name) { QFile f(name); return f.open(QIODevice::ReadOnly) ? QShader::fromSerialized(f.readAll()) : QShader(); } void ExampleRhiWidget::initialize(QRhiCommandBuffer *cb) { if (m_rhi != rhi()) { m_pipeline.reset(); m_rhi = rhi(); } if (!m_pipeline) { m_vbuf.reset(m_rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData))); m_vbuf->create(); m_ubuf.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64)); m_ubuf->create(); m_srb.reset(m_rhi->newShaderResourceBindings()); m_srb->setBindings({ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, m_ubuf.get()), }); m_srb->create(); m_pipeline.reset(m_rhi->newGraphicsPipeline()); m_pipeline->setShaderStages({ { QRhiShaderStage::Vertex, getShader(QLatin1String(":/shader_assets/color.vert.qsb")) }, { QRhiShaderStage::Fragment, getShader(QLatin1String(":/shader_assets/color.frag.qsb")) } }); QRhiVertexInputLayout inputLayout; inputLayout.setBindings({ { 5 * sizeof(float) } }); inputLayout.setAttributes({ { 0, 0, QRhiVertexInputAttribute::Float2, 0 }, { 0, 1, QRhiVertexInputAttribute::Float3, 2 * sizeof(float) } }); m_pipeline->setVertexInputLayout(inputLayout); m_pipeline->setShaderResourceBindings(m_srb.get()); m_pipeline->setRenderPassDescriptor(renderTarget()->renderPassDescriptor()); m_pipeline->create(); QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch(); resourceUpdates->uploadStaticBuffer(m_vbuf.get(), vertexData); cb->resourceUpdate(resourceUpdates); } const QSize outputSize = colorTexture()->pixelSize(); m_viewProjection = m_rhi->clipSpaceCorrMatrix(); m_viewProjection.perspective(45.0f, outputSize.width() / (float) outputSize.height(), 0.01f, 1000.0f); m_viewProjection.translate(0, 0, -4); } void ExampleRhiWidget::render(QRhiCommandBuffer *cb) { QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch(); m_rotation += 1.0f; QMatrix4x4 modelViewProjection = m_viewProjection; modelViewProjection.rotate(m_rotation, 0, 1, 0); resourceUpdates->updateDynamicBuffer(m_ubuf.get(), 0, 64, modelViewProjection.constData()); const QColor clearColor = QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f); cb->beginPass(renderTarget(), clearColor, { 1.0f, 0 }, resourceUpdates); cb->setGraphicsPipeline(m_pipeline.get()); const QSize outputSize = colorTexture()->pixelSize(); cb->setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height())); cb->setShaderResources(); const QRhiCommandBuffer::VertexInput vbufBinding(m_vbuf.get(), 0); cb->setVertexInput(0, 1, &vbufBinding); cb->draw(3); cb->endPass(); update(); }
Il s'agit d'un widget qui demande continuellement des mises à jour, limitées par le taux de présentation (vsync, en fonction du taux de rafraîchissement de l'écran). Si le rendu en continu n'est pas souhaité, l'appel à update() dans render() doit être supprimé et n'être lancé que lorsque la mise à jour du contenu rendu est nécessaire. Par exemple, si la rotation du cube doit être liée à la valeur d'un QSlider, il suffit de connecter le signal de changement de valeur du curseur à un slot ou à un lambda qui transmet la nouvelle valeur et appelle update().
Les nuanceurs de sommets et de fragments sont fournis en tant que GLSL de style Vulkan et doivent d'abord être traités par l'infrastructure de nuanceurs Qt. Ceci est réalisé soit en exécutant manuellement l'outil de ligne de commande qsb, soit en utilisant la fonction qt_add_shaders() dans CMake. L'implémentation de QRhiWidget charge ces fichiers pré-traités .qsb qui sont livrés avec l'application. Voir Qt Shader Tools pour plus d'informations sur l'infrastructure de traduction des shaders de Qt.
Le code source de ces nuanceurs pourrait être le suivant :
color.vert
#version 440
layout(location = 0) in vec4 position;
layout(location = 1) in vec3 color;
layout(location = 0) out vec3 v_color;
layout(std140, binding = 0) uniform buf {
mat4 mvp;
};
void main()
{
v_color = color;
gl_Position = mvp * position;
}color.frag
#version 440
layout(location = 0) in vec3 v_color;
layout(location = 0) out vec4 fragColor;
void main()
{
fragColor = vec4(v_color, 1.0);
}Le résultat est un widget qui affiche ce qui suit :

Pour un exemple complet, minimal et introductif, consultez l'exemple de widget RHI simple.
Pour un exemple avec plus de fonctionnalités et la démonstration d'autres concepts, voir l'exemple de widget RHI Cube.
QRhiWidget implique toujours un rendu dans une texture d'appui, et non directement dans la fenêtre (la surface ou la couche fournie par le système de fenêtrage pour la fenêtre native). Cela permet de composer correctement le contenu avec le reste de l'interface utilisateur basée sur le widget, et d'offrir une API simple et compacte, ce qui facilite la prise en main. Tout cela se fait au prix de ressources supplémentaires et d'un effet potentiel sur les performances. Cela est souvent parfaitement acceptable dans la pratique, mais les utilisateurs avancés doivent garder à l'esprit les avantages et les inconvénients des différentes approches. Reportez-vous à l'exemple de fenêtre RHI et comparez-le à l'exemple de widget RHI simple pour plus de détails sur les deux approches.
Reparenter un QRhiWidget dans une hiérarchie de widgets appartenant à une fenêtre différente (widget de niveau supérieur), ou faire du QRhiWidget lui-même un widget de niveau supérieur (en définissant le parent à nullptr), implique de changer le QRhi associé (et potentiellement de détruire l'ancien) alors que le QRhiWidget continue à rester en vie et en bonne santé. Pour ce faire, les implémentations robustes de QRhiWidget sont censées réimplémenter également la fonction virtuelle releaseResources() et abandonner leurs ressources QRhi comme elles le font dans le destructeur. L'exemple du widget RHI Cube le démontre en pratique.
Bien qu'il ne s'agisse pas d'un cas d'utilisation primaire, QRhiWidget permet également d'incorporer du code de rendu qui utilise directement une API graphique 3D telle que Vulkan, Metal, Direct 3D ou OpenGL. Voir QRhiCommandBuffer::beginExternal() pour plus de détails sur l'enregistrement de commandes natives dans une passe de rendu QRhi, ainsi que QRhiTexture::createFrom() pour un moyen d'envelopper une texture native existante et de l'utiliser avec QRhi dans une passe de rendu ultérieure. Notez cependant que la configurabilité de l'API graphique sous-jacente (ses caractéristiques de périphérique ou de contexte, ses couches, ses extensions, etc.) sera limitée puisque l'objectif principal de QRhiWidget est de fournir un environnement adapté au code de rendu basé sur QRhi, et non de permettre des moteurs de rendu étrangers arbitraires et potentiellement complexes.
Voir également QRhi, QShader, QOpenGLWidget, Exemple de widget RHI simple et Exemple de widget RHI cube.
Documentation sur les types de membres
enum class QRhiWidget::Api
Spécifie l'API 3D et le backend QRhi à utiliser
| Constante | Valeur |
|---|---|
QRhiWidget::Api::Null | 0 |
QRhiWidget::Api::OpenGL | 1 |
QRhiWidget::Api::Metal | 2 |
QRhiWidget::Api::Vulkan | 3 |
QRhiWidget::Api::Direct3D11 | 4 |
QRhiWidget::Api::Direct3D12 | 5 |
Voir aussi QRhi.
enum class QRhiWidget::TextureFormat
Spécifie le format de la texture sur laquelle QRhiWidget effectue le rendu.
| Constante | Valeur | Description de la texture |
|---|---|---|
QRhiWidget::TextureFormat::RGBA8 | 0 | Voir QRhiTexture::RGBA8. |
QRhiWidget::TextureFormat::RGBA16F | 1 | Voir QRhiTexture::RGBA16F. |
QRhiWidget::TextureFormat::RGBA32F | 2 | Voir QRhiTexture::RGBA32F. |
QRhiWidget::TextureFormat::RGB10A2 | 3 | Voir QRhiTexture::RGB10A2. |
Voir aussi QRhiTexture.
Documentation sur les biens
autoRenderTarget : bool
Paramètre actuel pour la maintenance automatique du tampon de profondeur et de la cible de rendu.
La valeur par défaut est true.
colorBufferFormat : TextureFormat
Cette propriété contrôle le format de la texture (ou du tampon de rendu) utilisée comme tampon de couleur. La valeur par défaut est TextureFormat::RGBA8. QRhiWidget prend en charge le rendu d'un sous-ensemble de formats pris en charge par QRhiTexture. Seuls les formats signalés comme pris en charge par QRhi::isTextureFormatSupported() doivent être spécifiés, sinon le rendu ne sera pas fonctionnel.
Remarque : la définition d'un nouveau format lorsque le widget est déjà initialisé et a effectué un rendu implique que tous les objets QRhiGraphicsPipeline créés par le moteur de rendu peuvent devenir inutilisables, si l'objet QRhiRenderPassDescriptor associé est désormais incompatible en raison du format de texture différent. De même que pour le changement dynamique de sampleCount, cela signifie que les implémentations de initialize() ou render() doivent alors se charger de libérer les pipelines existants et d'en créer de nouveaux.
Fonctions d'accès :
| QRhiWidget::TextureFormat | colorBufferFormat() const |
| void | setColorBufferFormat(QRhiWidget::TextureFormat format) |
Signal de notification :
| void | colorBufferFormatChanged(QRhiWidget::TextureFormat format) |
fixedColorBufferSize : QSize
La taille fixe, en pixels, de la texture associée à QRhiWidget. Elle est utile lorsque l'on souhaite obtenir une taille de texture fixe qui ne dépend pas de la taille du widget. Cette taille n'a aucun effet sur la géométrie du widget (sa taille et son emplacement dans la fenêtre de niveau supérieur), ce qui signifie que le contenu de la texture apparaîtra étiré (à l'échelle supérieure) ou réduit dans la zone du widget.
Par exemple, la définition d'une taille correspondant exactement au double de la taille (en pixels) du widget permet d'effectuer un suréchantillonnage 2x (rendu à une résolution deux fois supérieure, puis réduction implicite de l'échelle lors de la texturation du quadrant correspondant au widget dans la fenêtre). D'autre part, la définition d'une taille égale à la moitié de celle du widget permet d'obtenir un rendu à la moitié de la résolution, puis d'augmenter l'échelle des résultats.
Par défaut, la valeur est null QSize. Un QSize nul ou vide signifie que la taille de la texture suit la taille du QRhiWidget. (texture size = widget size * device pixel ratio).
Remarque : le rapport de pixel de l'appareil (le facteur d'échelle du compositeur du système) peut avoir un impact important sur les performances, puisqu'un facteur d'échelle de 2 (200 %) signifie un rendu à deux fois la résolution, donc deux fois ce que le développeur et le concepteur de l'interface utilisateur perçoivent comme la taille du widget, et donc une réduction effective du contenu, de manière similaire à ce qui se passe lorsque l'on définit cette propriété à deux fois la taille de pixel du widget sur un système où le rapport de pixel de l'appareil est de 1. Par conséquent, cette propriété devrait être rarement utilisée avec des tailles supérieures à la taille en pixels du widget, car de nombreux systèmes de bureau modernes n'en ont ni le besoin ni le budget de performance, lorsqu'un rapport de pixels supérieur à 1 est de toute façon utilisé par le système. Le principal cas d'utilisation de cette propriété est la définition d'une taille plus petite, afin d'obtenir un rendu à une résolution raisonnablement plus petite au lieu de suivre aveuglément la géométrie de la fenêtre, quelle que soit sa taille.
Fonctions d'accès :
| QSize | fixedColorBufferSize() const |
| void | setFixedColorBufferSize(QSize pixelSize) |
| void | setFixedColorBufferSize(int w, int h) |
Signal du notificateur :
| void | fixedColorBufferSizeChanged(const QSize &pixelSize) |
mirrorVertically : bool
Lorsque cette option est activée, l'image est retournée autour de l'axe X lors de la composition de la texture d'arrière-plan de QRhiWidget avec le reste du contenu du widget dans la fenêtre de niveau supérieur.
La valeur par défaut est false.
Fonctions d'accès :
| bool | isMirrorVerticallyEnabled() const |
| void | setMirrorVertically(bool enabled) |
Signal de notification :
| void | mirrorVerticallyChanged(bool enabled) |
sampleCount : int
Cette propriété contrôle le nombre d'échantillons pour l'anticrénelage multi-échantillon. Par défaut, la valeur est 1, ce qui signifie que le MSAA est désactivé.
Les valeurs valides sont 1, 4, 8, et parfois 16 et 32. QRhi::supportedSampleCounts() peut être utilisé pour demander le nombre d'échantillons pris en charge au moment de l'exécution, mais les applications devraient généralement demander 1 (pas de MSAA), 4x (MSAA normal) ou 8x (MSAA élevé).
Remarque : la définition d'une nouvelle valeur implique que tous les objets QRhiGraphicsPipeline créés par le moteur de rendu doivent désormais utiliser le même nombre d'échantillons. Les objets QRhiGraphicsPipeline existants créés avec un nombre d'échantillons différent ne doivent plus être utilisés. Lorsque la valeur change, tous les tampons de couleur et de profondeur sont détruits et recréés automatiquement, et initialize() est invoqué à nouveau. Cependant, lorsque autoRenderTarget est false, c'est à l'application de gérer cela en ce qui concerne le tampon de profondeur ou les tampons de couleur supplémentaires.
Le passage du nombre d'échantillons de la valeur par défaut de 1 à une valeur plus élevée implique que colorTexture() devient nullptr et que msaaColorBuffer() commence à renvoyer un objet valide. Le retour à 1 (ou 0) implique l'inverse : lors du prochain appel à initialize(), msaaColorBuffer() renverra nullptr, tandis que colorTexture() redeviendra valide. En outre, resolveTexture() renvoie un objet valide (non multi-échantillon) QRhiTexture chaque fois que le nombre d'échantillons est supérieur à 1 (c'est-à-dire que le MSAA est utilisé).
Fonctions d'accès :
| int | sampleCount() const |
| void | setSampleCount(int samples) |
Signal de notification :
| void | sampleCountChanged(int samples) |
Voir également msaaColorBuffer() et resolveTexture().
Documentation des fonctions membres
[explicit] QRhiWidget::QRhiWidget(QWidget *parent = nullptr, Qt::WindowFlags f = {})
Construit un widget qui est un enfant de parent, avec les drapeaux de widget fixés à f.
[override virtual noexcept] QRhiWidget::~QRhiWidget()
Destructeur.
QRhiWidget::Api QRhiWidget::api() const
Renvoie l'API graphique actuellement définie (QRhi backend).
Voir aussi setApi().
[protected] QRhiTexture *QRhiWidget::colorTexture() const
Renvoie la texture servant de tampon de couleur pour le widget.
Ne doit être appelé qu'à partir de initialize() et render().
Contrairement au tampon de profondeur et à QRhiRenderTarget, cette texture est toujours disponible et est gérée par QRhiWidget, indépendamment de la valeur de autoRenderTarget.
Remarque : lorsque sampleCount est plus grand que 1 et que l'anticrénelage multi-échantillon est activé, la valeur de retour est nullptr. Il convient plutôt d'interroger QRhiRenderBuffer en appelant msaaColorBuffer().
Note : La taille de la texture d'appui et le nombre d'échantillons peuvent également être demandés via la valeur QRhiRenderTarget renvoyée par renderTarget(). Cette méthode peut s'avérer plus pratique et plus compacte que l'interrogation à partir de QRhiTexture ou QRhiRenderBuffer, car elle fonctionne indépendamment de l'utilisation ou non du multi-échantillonnage.
Voir aussi msaaColorBuffer(), depthStencilBuffer(), renderTarget() et resolveTexture().
[protected] QRhiRenderBuffer *QRhiWidget::depthStencilBuffer() const
Renvoie le tampon de profondeur utilisé par le rendu du widget.
Ne doit être appelé qu'à partir de initialize() et render().
Disponible uniquement si autoRenderTarget est true. Sinon, la valeur renvoyée est nullptr et c'est à la réimplémentation de initialize() de créer et de gérer un tampon de profondeur et un QRhiTextureRenderTarget.
Voir également colorTexture() et renderTarget().
[override virtual protected] bool QRhiWidget::event(QEvent *e)
Réimplémente : QWidget::event(QEvent *event).
[signal] void QRhiWidget::frameSubmitted()
Ce signal est émis après que la fenêtre de premier niveau du widget a terminé sa composition et a submitted a frame.
QImage QRhiWidget::grabFramebuffer() const
Rend une nouvelle image, lit le contenu de la texture et le renvoie sous forme de QImage.
En cas d'erreur, une adresse QImage nulle est renvoyée.
L'adresse QImage renvoyée aura un format de QImage::Format_RGBA8888, QImage::Format_RGBA16FPx4, QImage::Format_RGBA32FPx4, ou QImage::Format_BGR30, en fonction de colorBufferFormat().
QRhiWidget ne connaît pas l'approche du moteur de rendu en matière de mélange et de composition, et ne peut donc pas savoir si la sortie comporte une prémultiplication de l'alpha dans les valeurs de couleur RVB. Ainsi, les formats _Premultiplied QImage ne sont jamais utilisés pour le retour QImage, même lorsque cela serait approprié. Il appartient à l'appelant de réinterpréter les données résultantes comme il l'entend.
Remarque : cette fonction peut également être appelée lorsque le site QRhiWidget n'est pas ajouté à une hiérarchie de widgets appartenant à une fenêtre de premier niveau à l'écran. Cela permet de générer une image à partir d'un rendu 3D hors écran.
La fonction est nommée grabFramebuffer() par souci de cohérence avec QOpenGLWidget et QQuickWidget. Ce n'est pas la seule façon d'obtenir des données d'image côté CPU à partir du contenu de QRhiWidget: appeler QWidget::grab() sur un QRhiWidget, ou un ancêtre de celui-ci, est également fonctionnel (renvoyant un QPixmap). En plus de travailler directement avec QImage, un autre avantage de grabFramebuffer() est qu'il peut être légèrement plus performant, simplement parce qu'il n'a pas besoin de passer par le reste de l'infrastructure QWidget mais peut immédiatement déclencher le rendu d'une nouvelle image et ensuite effectuer la lecture.
Voir aussi setColorBufferFormat().
[virtual protected] void QRhiWidget::initialize(QRhiCommandBuffer *cb)
Appelée lorsque le widget est initialisé pour la première fois, lorsque la taille, le format ou le nombre d'échantillons de la texture associée change, ou lorsque QRhi et la texture changent pour quelque raison que ce soit. La fonction est censée maintenir (créer si elle n'a pas encore été créée, ajuster et reconstruire si la taille a changé) les ressources graphiques utilisées par le code de rendu dans render().
Pour interroger les objets QRhi, QRhiTexture et d'autres objets connexes, appelez rhi(), colorTexture(), depthStencilBuffer() et renderTarget().
Lorsque la taille du widget change, l'objet QRhi, la texture du tampon de couleur et les objets du tampon du pochoir de profondeur sont tous les mêmes instances (les getters renvoient donc les mêmes pointeurs) qu'auparavant, mais les tampons de couleur et de profondeur/pochoir auront probablement été reconstruits, ce qui signifie que l'objet size et la ressource de texture native sous-jacente peuvent être différents de ceux de la dernière invocation.
Les réimplémentations doivent également être préparées au fait que l'objet QRhi et la texture du tampon de couleur peuvent changer entre les invocations de cette fonction. Un cas particulier où les objets seront différents est celui de l'exécution d'une fonction grabFramebuffer() avec un widget qui n'est pas encore affiché et qui rend le widget visible à l'écran à l'intérieur d'un widget de niveau supérieur. Dans ce cas, la saisie se fera avec un QRhi dédié qui sera ensuite remplacé par le QRhi associé à la fenêtre de niveau supérieur dans les invocations ultérieures de initialize() et render(). Un autre cas, plus courant, est celui où le widget est réparti de manière à appartenir à une nouvelle fenêtre de premier niveau. Dans ce cas, le QRhi et toutes les ressources connexes gérées par le QRhiWidget seront des instances différentes qu'auparavant lors de l'appel ultérieur à cette fonction. Il est alors important que toutes les ressources QRhi créées précédemment par la sous-classe soient détruites car elles appartiennent à l'ancienne QRhi qui ne doit plus être utilisée par le widget.
Lorsque autoRenderTarget est true, ce qui est le cas par défaut, un crayon de profondeur QRhiRenderBuffer et un QRhiTextureRenderTarget associé à colorTexture() (ou msaaColorBuffer()) et le tampon du crayon de profondeur sont créés et gérés automatiquement. Les réimplémentations de initialize() et render() peuvent interroger ces objets via depthStencilBuffer() et renderTarget(). Lorsque autoRenderTarget est remplacé par false, ces objets ne sont plus créés et gérés automatiquement. C'est plutôt à l'implémentation d'initialize() de créer des tampons et de configurer la cible de rendu comme elle l'entend. Lors de la gestion manuelle d'attachements supplémentaires de couleur ou de profondeur pour la cible de rendu, leur taille et leur nombre d'échantillons doivent toujours suivre la taille et le nombre d'échantillons de colorTexture() / msaaColorBuffer(), sinon des erreurs de rendu ou de validation de l'API 3D risquent de se produire.
Les ressources graphiques créées par la sous-classe sont censées être libérées dans l'implémentation du destructeur de la sous-classe.
cb est l'adresse QRhiCommandBuffer pour le cadre actuel du widget. La fonction est appelée lorsqu'une image est en cours d'enregistrement, mais sans passe de rendu active. Le tampon de commande est fourni principalement pour permettre la mise en file d'attente de resource updates sans reporter à render().
Voir également render().
bool QRhiWidget::isDebugLayerEnabled() const
Retourne true si une couche de débogage ou de validation sera demandée si elle est applicable à l'API graphique utilisée.
Voir aussi setDebugLayerEnabled().
[protected] QRhiRenderBuffer *QRhiWidget::msaaColorBuffer() const
Renvoie le tampon de rendu servant de tampon de couleur multi-échantillon pour le widget.
Ne doit être appelé qu'à partir de initialize() et render().
Lorsque sampleCount est plus grand que 1, et que l'antialisation multi-échantillon est activée, le tampon retourné QRhiRenderBuffer a un nombre d'échantillons correspondant et sert de tampon de couleur. Les pipelines graphiques utilisés pour effectuer le rendu dans ce tampon doivent être créés avec le même nombre d'échantillons, et le nombre d'échantillons du tampon de profondeur doit également correspondre. Le contenu du multi-échantillon est censé être résolu dans la texture renvoyée par resolveTexture(). Lorsque autoRenderTarget est true, renderTarget() est configuré automatiquement pour faire cela, en configurant msaaColorBuffer() comme renderbuffer de l'attachement de couleur 0 et resolveTexture() comme son resolveTexture.
Lorsque MSAA n'est pas utilisé, la valeur de retour est nullptr. Utilisez alors colorTexture() à la place.
Selon l'API graphique 3D sous-jacente, il peut n'y avoir aucune différence pratique entre les textures multi-échantillons et les tampons de rendu de couleur avec un nombre d'échantillons supérieur à 1 (QRhi peut simplement mapper les deux vers le même type de ressource native). Certaines API plus anciennes peuvent cependant faire la différence entre les textures et les renderbuffers. Afin de prendre en charge OpenGL ES 3.0, où les renderbuffers multi-échantillons sont disponibles, mais pas les textures multi-échantillons, QRhiWidget effectue toujours le MSAA en utilisant un multi-échantillon QRhiRenderBuffer comme attachement de couleur (et jamais un multi-échantillon QRhiTexture).
Remarque : la taille de la texture de soutien et le nombre d'échantillons peuvent également être demandés par l'intermédiaire de QRhiRenderTarget renvoyé par renderTarget(). Cette méthode peut s'avérer plus pratique et plus compacte que l'interrogation à partir de QRhiTexture ou QRhiRenderBuffer, car elle fonctionne indépendamment de l'utilisation ou non du multi-échantillonnage.
Voir aussi colorTexture(), depthStencilBuffer(), renderTarget() et resolveTexture().
[override virtual protected] void QRhiWidget::paintEvent(QPaintEvent *e)
Réimplémente : QWidget::paintEvent(QPaintEvent *event).
Gère les événements de peinture.
L'appel à QWidget::update() entraînera l'envoi d'un événement de peinture e, et donc l'invocation de cette fonction. L'envoi de l'événement est asynchrone et se produit à un moment donné après le retour de update(). Cette fonction appellera ensuite, après une certaine préparation, la fonction virtuelle render() pour mettre à jour le contenu de la texture associée à QRhiWidget. La fenêtre de premier niveau du widget composera alors la texture avec le reste de la fenêtre.
[virtual protected] void QRhiWidget::releaseResources()
Appelé lorsqu'il est nécessaire de libérer les ressources graphiques de manière anticipée.
Normalement, cela ne se produit pas pour un QRhiWidget qui est ajouté à la hiérarchie des enfants d'un widget de premier niveau et qui y reste pour le reste de sa durée de vie et de celle du widget de premier niveau. Dans de nombreux cas, il n'est donc pas nécessaire de réimplémenter cette fonction, par exemple parce que l'application n'a jamais qu'un seul widget de premier niveau (fenêtre native). Cependant, lorsque le reparentage du widget (ou d'un de ses ancêtres) est impliqué, la réimplémentation de cette fonction deviendra nécessaire dans les sous-classes robustes et bien écrites de QRhiWidget.
Lorsque cette fonction est appelée, l'implémentation est censée détruire toutes les ressources QRhi (objetsQRhiBuffer, QRhiTexture, etc.), de la même manière qu'elle est censée le faire dans le destructeur. L'annulation, l'utilisation d'un pointeur intelligent ou la mise en place d'un drapeau resources-invalid seront également nécessaires, car initialize() sera appelé par la suite. Notez cependant qu'il est erroné de reporter la libération des ressources à la fonction initialize(). Si cette fonction est appelée, la ressource doit être libérée avant de revenir. Notez également que l'implémentation de cette fonction ne remplace pas le destructeur de classe (ou les pointeurs intelligents) : les ressources graphiques doivent toujours être libérées dans les deux cas.
Voir l'exemple de widget Cube RHI pour un exemple de cette fonction en action. Ici, le bouton qui fait basculer le site QRhiWidget entre le statut de widget enfant (en raison de la présence d'un widget parent) et celui de widget de niveau supérieur (en raison de l'absence de widget parent) déclenchera l'invocation de cette fonction puisque le widget de niveau supérieur associé, la fenêtre native et le site QRhi changent tous au cours de la durée de vie du site QRhiWidget, le site QRhi précédemment utilisé étant détruit, ce qui implique une libération anticipée des ressources associées gérées par le site QRhiWidget toujours en vie.
Un autre cas où cette fonction est appelée est lorsque grabFramebuffer() est utilisé avec un QRhiWidget qui n'est pas ajouté à une fenêtre visible, c'est-à-dire que le rendu est effectué hors écran. Si, par la suite, ce QRhiWidget est rendu visible ou ajouté à une hiérarchie de widgets visibles, le QRhi associé passera de celui utilisé temporairement pour le rendu hors écran à celui dédié à la fenêtre, ce qui déclenchera également cette fonction.
Voir également initialize().
[virtual protected] void QRhiWidget::render(QRhiCommandBuffer *cb)
Appelée lorsque le contenu du widget (c'est-à-dire le contenu de la texture) doit être mis à jour.
Il y a toujours au moins un appel à initialize() avant que cette fonction ne soit appelée.
Pour demander des mises à jour, appelez QWidget::update(). Appeler update() à partir de render() conduira à une mise à jour continue, ralentie par vsync.
cb est l'adresse QRhiCommandBuffer pour le cadre actuel du widget. La fonction est appelée alors qu'une image est en cours d'enregistrement, mais sans passe de rendu active.
Voir également initialize().
[signal] void QRhiWidget::renderFailed()
Ce signal est émis chaque fois que le widget est censé effectuer un rendu sur sa texture d'arrière-plan (soit en raison d'un widget update, soit en raison d'un appel à grabFramebuffer()), mais qu'il n'y a pas de QRhi à utiliser pour le widget, probablement en raison de problèmes liés à la configuration graphique.
Ce signal peut être émis plusieurs fois lorsqu'un problème survient. Ne supposez pas qu'il n'est émis qu'une seule fois. Connectez-vous à Qt::SingleShotConnection si le code de gestion des erreurs ne doit être notifié qu'une seule fois.
[protected] QRhiRenderTarget *QRhiWidget::renderTarget() const
Renvoie l'objet cible de rendu qui doit être utilisé avec QRhiCommandBuffer::beginPass() dans les réimplémentations de render().
Ne doit être appelé qu'à partir de initialize() et render().
Disponible uniquement si autoRenderTarget est true. Sinon, la valeur renvoyée est nullptr et il appartient à la réimplémentation de initialize() de créer et de gérer un tampon de profondeur et un QRhiTextureRenderTarget.
Lors de la création de graphics pipelines, un QRhiRenderPassDescriptor est nécessaire. Celui-ci peut être interrogé à partir de l'adresse QRhiTextureRenderTarget renvoyée en appelant renderPassDescriptor().
Voir aussi colorTexture() et depthStencilBuffer().
[override virtual protected] void QRhiWidget::resizeEvent(QResizeEvent *e)
Réimplémente : QWidget::resizeEvent(QResizeEvent *event).
Gère les événements de redimensionnement qui sont passés dans le paramètre e event. Appelle la fonction virtuelle initialize().
Remarque : évitez de surcharger cette fonction dans les classes dérivées. Si ce n'est pas possible, assurez-vous que l'implémentation de QRhiWidget est également invoquée. Dans le cas contraire, l'objet texture sous-jacent et les ressources associées ne seront pas redimensionnés correctement, ce qui entraînera un rendu incorrect.
[protected] QRhiTexture *QRhiWidget::resolveTexture() const
Renvoie la texture sans multi-échantillon dans laquelle le contenu multi-échantillon est résolu.
Le résultat est nullptr lorsque l'anticrénelage multi-échantillon n'est pas activé.
Ne doit être appelé qu'à partir de initialize() et render().
Lorsque le MSAA est activé, il s'agit de la texture qui est composée avec le reste du contenu de QWidget à l'écran. Cependant, le rendu de QRhiWidget doit cibler le (multi-échantillon) QRhiRenderBuffer renvoyé par msaaColorBuffer(). Lorsque autoRenderTarget est true, cela est pris en charge par le QRhiRenderTarget renvoyé par renderTarget(). Sinon, c'est au code de la sous-classe de configurer correctement un objet de cible de rendu avec le tampon de couleur et les textures de résolution.
Voir aussi colorTexture().
[protected] QRhi *QRhiWidget::rhi() const
Renvoie l'objet actuel QRhi.
Ne doit être appelé qu'à partir de initialize() et render().
void QRhiWidget::setApi(QRhiWidget::Api api)
Définit l'API graphique et le backend QRhi à utiliser pour api.
Attention : Cette fonction doit être appelée suffisamment tôt, avant que le widget ne soit ajouté à une hiérarchie de widgets et affiché à l'écran. Par exemple, essayez d'appeler la fonction pour le constructeur de la sous-classe. Si elle est appelée trop tard, la fonction n'aura aucun effet.
La valeur par défaut dépend de la plateforme : Metal sur macOS et iOS, Direct 3D 11 sur Windows, OpenGL sinon.
La valeur api ne peut être définie qu'une seule fois pour le widget et sa fenêtre de premier niveau. Une fois la valeur définie et prise en compte, la fenêtre ne peut utiliser que cette API et le backend QRhi pour le rendu. Toute tentative de définir une autre valeur ou d'ajouter un autre QRhiWidget avec un api différent ne fonctionnera pas comme prévu.
Voir aussi setColorBufferFormat(), setDebugLayerEnabled(), et api().
[protected] void QRhiWidget::setAutoRenderTarget(bool enabled)
Contrôle si un crayon de profondeur QRhiRenderBuffer et un QRhiTextureRenderTarget sont créés et maintenus automatiquement par le widget. La valeur par défaut est true.
En mode automatique, la taille et le nombre d'échantillons du tampon du pochoir de profondeur suivent les paramètres de la texture du tampon de couleur. En mode non automatique, renderTarget() et depthStencilBuffer() renvoient toujours nullptr et c'est alors à l'implémentation de initialize() de l'application de s'occuper de la configuration et de la gestion de ces objets.
Appelez cette fonction avec enabled fixé à false dès le début, par exemple dans le constructeur de la classe dérivée, pour désactiver le mode automatique.
void QRhiWidget::setDebugLayerEnabled(bool enable)
Demande la couche de débogage ou de validation de l'API graphique sous-jacente lorsque enable est vrai.
Attention : Cette fonction doit être appelée suffisamment tôt, avant que le widget ne soit ajouté à une hiérarchie de widgets et affiché à l'écran. Par exemple, essayez d'appeler la fonction pour le constructeur de la sous-classe. Si elle est appelée trop tard, la fonction n'aura aucun effet.
Applicable pour Vulkan et Direct 3D.
Par défaut, cette fonction est désactivée.
Voir aussi setApi() et isDebugLayerEnabled().
© 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.