QRhiWidget Class

Die Klasse QRhiWidget ist ein Widget zum Rendern von 3D-Grafiken über eine beschleunigte Grafik-API, wie Vulkan, Metal oder Direct 3D. Mehr...

Kopfzeile: #include <QRhiWidget>
CMake: find_package(Qt6 REQUIRED COMPONENTS Widgets)
target_link_libraries(mytarget PRIVATE Qt6::Widgets)
qmake: QT += widgets
Seit: Qt 6.7
Erbt: QWidget
Status: Vorläufig

Diese Klasse befindet sich in der Entwicklung und kann sich noch ändern.

Öffentliche Typen

enum class Api { Null, OpenGL, Metal, Vulkan, Direct3D11, Direct3D12 }
enum class TextureFormat { RGBA8, RGBA16F, RGBA32F, RGB10A2 }

Eigenschaften

Öffentliche Funktionen

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)

Signale

void colorBufferFormatChanged(QRhiWidget::TextureFormat format)
void fixedColorBufferSizeChanged(const QSize &pixelSize)
void frameSubmitted()
void mirrorVerticallyChanged(bool enabled)
void renderFailed()
void sampleCountChanged(int samples)

Geschützte Funktionen

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)

Reimplementierte geschützte Funktionen

virtual bool event(QEvent *e) override
virtual void paintEvent(QPaintEvent *e) override
virtual void resizeEvent(QResizeEvent *e) override

Detaillierte Beschreibung

Hinweis: QRhiWidget befindet sich in der Tech-Preview von Qt 6.7. Die API befindet sich in der Entwicklung und kann sich noch ändern.

QRhiWidget bietet Funktionen zur Anzeige von 3D-Inhalten, die über die QRhi APIs gerendert wurden, in einer QWidget-basierten Anwendung. In vielerlei Hinsicht ist es das portable Äquivalent von QOpenGLWidget, das nicht an eine einzige 3D-Grafik-API gebunden ist, sondern mit allen APIs funktionieren kann, die QRhi unterstützt (z. B. Direct 3D 11/12, Vulkan, Metal und OpenGL).

Es wird erwartet, dass QRhiWidget subclassed wird. Um in die 2D-Textur zu rendern, die implizit von QRhiWidget erstellt und verwaltet wird, sollten Unterklassen die virtuellen Funktionen initialize() und render() reimplementieren.

Die Größe der Textur wird sich standardmäßig an die Größe des Widgets anpassen. Wenn Sie eine feste Größe bevorzugen, setzen Sie eine feste Größe in Pixeln, indem Sie setFixedColorBufferSize() aufrufen.

Zusätzlich zur Textur, die als Farbpuffer dient, werden auch ein Tiefen-/Schablonenpuffer und ein Rendering-Ziel, das diese miteinander verbindet, implizit verwaltet.

Die QRhi für das Top-Level-Fenster des Widgets ist so konfiguriert, dass sie standardmäßig ein plattformspezifisches Backend und eine Grafik-API verwendet: Metal unter macOS und iOS, Direct 3D 11 unter Windows, ansonsten OpenGL. Rufen Sie setApi() auf, um dies außer Kraft zu setzen.

Hinweis: Ein einzelnes Widget-Fenster kann nur ein QRhi Backend und damit eine einzige 3D-Grafik-API verwenden. Wenn zwei QRhiWidget- oder QQuickWidget -Widgets in der Widget-Hierarchie des Fensters unterschiedliche APIs anfordern, wird nur eines von ihnen korrekt funktionieren.

Hinweis: Während QRhiWidget eine öffentliche Qt-API ist, bietet die QRhi -Klassenfamilie im Qt Gui-Modul, einschließlich QRhi, QShader und QShaderDescription, begrenzte Kompatibilitätsgarantien. Es gibt keine Quell- oder Binärkompatibilitätsgarantien für diese Klassen, was bedeutet, dass die API nur mit der Qt-Version funktioniert, mit der die Anwendung entwickelt wurde. Quelltext-inkompatible Änderungen sollen jedoch so gering wie möglich gehalten werden und werden nur in kleineren Versionen (6.7, 6.8, usw.) vorgenommen. qrhiwidget.h enthält keine QRhi-bezogenen Header direkt. Um diese Klassen bei der Implementierung einer QRhiWidget-Unterklasse zu verwenden, verlinken Sie auf Qt::GuiPrivate (wenn Sie CMake verwenden) und fügen Sie die entsprechenden Header mit dem Präfix rhi ein, zum Beispiel #include <rhi/qrhi.h>.

Ein Beispiel für eine einfache QRhiWidget-Unterklasse, die ein Dreieck darstellt, ist das folgende:

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();
}

Dies ist ein Widget, das kontinuierlich Aktualisierungen anfordert, gedrosselt durch die Darstellungsrate (vsync, abhängig von der Bildwiederholrate). Wenn ein kontinuierliches Rendering nicht erwünscht ist, sollte der update()-Aufruf in render() entfernt werden und stattdessen nur dann erfolgen, wenn eine Aktualisierung des gerenderten Inhalts erforderlich ist. Wenn zum Beispiel die Drehung des Würfels an den Wert eines QSlider gebunden sein soll, reicht es aus, das Wertänderungssignal des Schiebereglers mit einem Slot oder Lambda zu verbinden, das den neuen Wert weiterleitet und update() aufruft.

Die Vertex- und Fragment-Shader werden als GLSL im Vulkan-Stil bereitgestellt und müssen zunächst von der Qt-Shader-Infrastruktur verarbeitet werden. Dies geschieht entweder durch manuelles Ausführen des Kommandozeilen-Tools qsb oder durch Verwendung der Funktion qt_add_shaders() in CMake. Die QRhiWidget-Implementierung lädt diese vorverarbeiteten .qsb Dateien, die mit der Anwendung ausgeliefert werden. Siehe Qt Shader Tools für weitere Informationen über die Shader-Übersetzungsinfrastruktur von Qt.

Der Quellcode für diese Shader könnte folgendermaßen aussehen:

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);
}

Das Ergebnis ist ein Widget, das Folgendes anzeigt:

Ein vollständiges, minimales, einführendes Beispiel finden Sie im Simple RHI Widget Example.

Für ein Beispiel mit mehr Funktionalität und zur Demonstration weiterer Konzepte siehe das Cube RHI Widget Example.

Bei QRhiWidget wird immer in eine Hintergrundtextur gerendert, nicht direkt in das Fenster (die Oberfläche oder Ebene, die vom Windowing-System für das native Fenster bereitgestellt wird). Dies ermöglicht eine korrekte Komposition des Inhalts mit dem Rest der Widget-basierten UI und bietet eine einfache und kompakte API, die den Einstieg erleichtert. All dies geht auf Kosten zusätzlicher Ressourcen und einer möglichen Beeinträchtigung der Leistung. Dies ist in der Praxis oft durchaus akzeptabel, aber fortgeschrittene Benutzer sollten die Vor- und Nachteile der verschiedenen Ansätze im Auge behalten. Einzelheiten zu den beiden Ansätzen finden Sie im RHI Window Example und im Vergleich mit dem Simple RHI Widget Example.

Wenn Sie ein QRhiWidget in eine Widget-Hierarchie einfügen, die zu einem anderen Fenster (Top-Level-Widget) gehört, oder wenn Sie das QRhiWidget selbst zu einem Top-Level-Widget machen (indem Sie das Parent auf nullptr setzen), müssen Sie das zugehörige QRhi ändern (und möglicherweise das alte Widget zerstören), während das QRhiWidget weiterlebt. Um dies zu unterstützen, wird von robusten QRhiWidget-Implementierungen erwartet, dass sie die virtuelle Funktion releaseResources() ebenfalls reimplementieren und ihre QRhi -Ressourcen genau wie im Destruktor löschen. Das Cube RHI Widget Beispiel demonstriert dies in der Praxis.

QRhiWidget ist zwar kein primärer Anwendungsfall, ermöglicht aber auch die Einbindung von Rendering-Code, der direkt eine 3D-Grafik-API wie Vulkan, Metal, Direct 3D oder OpenGL verwendet. Siehe QRhiCommandBuffer::beginExternal() für Details zur Aufzeichnung nativer Befehle in einem QRhi Rendering-Durchgang, sowie QRhiTexture::createFrom() für eine Möglichkeit, eine vorhandene native Textur zu umhüllen und sie dann mit QRhi in einem nachfolgenden Rendering-Durchgang zu verwenden. Beachte jedoch, dass die Konfigurierbarkeit der zugrundeliegenden Grafik-API (ihre Geräte- oder Kontext-Features, Ebenen, Erweiterungen usw.) begrenzt sein wird, da das primäre Ziel von QRhiWidget darin besteht, eine Umgebung bereitzustellen, die für QRhi-basierten Rendering-Code geeignet ist, und nicht darin, beliebige, potenziell komplexe, fremde Rendering-Engines zu ermöglichen.

Siehe auch QRhi, QShader, QOpenGLWidget, Simple RHI Widget Example und Cube RHI Widget Example.

Member Type Dokumentation

enum class QRhiWidget::Api

Gibt die zu verwendende 3D-API und das QRhi Backend an

KonstanteWert
QRhiWidget::Api::Null0
QRhiWidget::Api::OpenGL1
QRhiWidget::Api::Metal2
QRhiWidget::Api::Vulkan3
QRhiWidget::Api::Direct3D114
QRhiWidget::Api::Direct3D125

Siehe auch QRhi.

enum class QRhiWidget::TextureFormat

Gibt das Format der Textur an, auf die QRhiWidget gerendert wird.

KonstanteWertBeschreibung
QRhiWidget::TextureFormat::RGBA80Siehe QRhiTexture::RGBA8.
QRhiWidget::TextureFormat::RGBA16F1Siehe QRhiTexture::RGBA16F.
QRhiWidget::TextureFormat::RGBA32F2Siehe QRhiTexture::RGBA32F.
QRhiWidget::TextureFormat::RGB10A23Siehe QRhiTexture::RGB10A2.

Siehe auch QRhiTexture.

Eigenschaft Dokumentation

autoRenderTarget : const bool

Die aktuelle Einstellung für die automatische Wartung des Tiefenschablonenpuffers und des Renderziels.

Standardmäßig lautet der Wert true.

colorBufferFormat : TextureFormat

Diese Eigenschaft steuert das Texturformat der als Farbpuffer verwendeten Textur (oder des Renderbuffers). Der Standardwert ist TextureFormat::RGBA8. QRhiWidget unterstützt das Rendering in einer Teilmenge der von QRhiTexture unterstützten Formate. Es sollten nur Formate angegeben werden, die von QRhi::isTextureFormatSupported() als unterstützt gemeldet werden, da das Rendering sonst nicht funktioniert.

Hinweis: Das Setzen eines neuen Formats, wenn das Widget bereits initialisiert ist und gerendert hat, bedeutet, dass alle QRhiGraphicsPipeline Objekte, die vom Renderer erstellt wurden, unbrauchbar werden können, wenn das zugehörige QRhiRenderPassDescriptor nun aufgrund des unterschiedlichen Texturformats inkompatibel ist. Ähnlich wie bei der dynamischen Änderung von sampleCount bedeutet dies, dass die Implementierungen von initialize() oder render() sich dann um die Freigabe der bestehenden Pipelines und die Erstellung neuer Pipelines kümmern müssen.

Zugriffsfunktionen:

QRhiWidget::TextureFormat colorBufferFormat() const
void setColorBufferFormat(QRhiWidget::TextureFormat format)

Notifier Signal:

void colorBufferFormatChanged(QRhiWidget::TextureFormat format)

fixedColorBufferSize : QSize

Die feste Größe, in Pixeln, der zugehörigen Textur von QRhiWidget. Relevant, wenn eine feste Texturgröße gewünscht ist, die nicht von der Größe des Widgets abhängt. Diese Größe hat keine Auswirkung auf die Geometrie des Widgets (seine Größe und Platzierung innerhalb des Top-Level-Fensters), was bedeutet, dass der Inhalt der Textur gestreckt (vergrößert) oder verkleinert auf die Fläche des Widgets erscheint.

Wenn Sie z. B. eine Größe festlegen, die genau doppelt so groß ist wie die (Pixel-)Größe des Widgets, führen Sie effektiv ein 2x-Supersampling durch (Rendering mit doppelter Auflösung und dann implizite Verkleinerung bei der Texturierung des dem Widget entsprechenden Quad im Fenster).

Standardmäßig ist der Wert eine Null QSize. Eine Null oder ein leerer QSize bedeutet, dass die Größe der Textur der Größe von QRhiWidget folgt. (texture size = widget size * device pixel ratio).

Zugriffsfunktionen:

QSize fixedColorBufferSize() const
void setFixedColorBufferSize(QSize pixelSize)
void setFixedColorBufferSize(int w, int h)

Benachrichtigungssignal:

void fixedColorBufferSizeChanged(const QSize &pixelSize)

mirrorVertically : bool

Wenn diese Option aktiviert ist, wird das Bild um die X-Achse gespiegelt, wenn die Hintergrundtextur von QRhiWidget mit dem restlichen Inhalt des Widgets im Fenster der obersten Ebene zusammengesetzt wird.

Der Standardwert ist false.

Zugriffsfunktionen:

bool isMirrorVerticallyEnabled() const
void setMirrorVertically(bool enabled)

Benachrichtigungssignal:

void mirrorVerticallyChanged(bool enabled)

sampleCount : int

Diese Eigenschaft steuert die Anzahl der Samples für Multisample Antialiasing. Standardmäßig ist der Wert 1, was bedeutet, dass MSAA deaktiviert ist.

Gültige Werte sind 1, 4, 8, und manchmal 16 und 32. QRhi::supportedSampleCounts() kann verwendet werden, um die unterstützten Samplezahlen zur Laufzeit abzufragen, aber normalerweise sollten Anwendungen 1 (kein MSAA), 4x (normales MSAA) oder 8x (hohes MSAA) anfordern.

Hinweis: Das Setzen eines neuen Wertes bedeutet, dass alle QRhiGraphicsPipeline Objekte, die vom Renderer erstellt werden, von da an dieselbe Sampleanzahl verwenden müssen. Vorhandene QRhiGraphicsPipeline Objekte, die mit einer anderen Sampleanzahl erstellt wurden, dürfen nicht mehr verwendet werden. Wenn sich der Wert ändert, werden alle Farb- und Tiefenschablonenpuffer automatisch zerstört und neu erstellt, und initialize() wird erneut aufgerufen. Wenn autoRenderTarget jedoch false ist, muss die Anwendung dies in Bezug auf den Tiefenschablonenpuffer oder zusätzliche Farbpuffer verwalten.

Wenn Sie die Anzahl der Abtastungen von der Standardeinstellung 1 auf einen höheren Wert ändern, wird colorTexture() zu nullptr und msaaColorBuffer() beginnt, ein gültiges Objekt zurückzugeben. Ein Zurückschalten auf 1 (oder 0) bedeutet das Gegenteil: Beim nächsten Aufruf von initialize() wird msaaColorBuffer() nullptr zurückgeben, während colorTexture() wieder gültig wird. Darüber hinaus gibt resolveTexture() ein gültiges (Nicht-Mehrproben-) QRhiTexture zurück, wenn die Anzahl der Proben größer als 1 ist (d. h. wenn MSAA verwendet wird).

Zugriffsfunktionen:

int sampleCount() const
void setSampleCount(int samples)

Melder-Signal:

void sampleCountChanged(int samples)

Siehe auch msaaColorBuffer() und resolveTexture().

Dokumentation der Mitgliedsfunktionen

[explicit] QRhiWidget::QRhiWidget(QWidget *parent = nullptr, Qt::WindowFlags f = {})

Konstruiert ein Widget, das ein Kind von parent ist, wobei die Widget-Flags auf f gesetzt sind.

[override virtual noexcept] QRhiWidget::~QRhiWidget()

Zerstörer.

QRhiWidget::Api QRhiWidget::api() const

Gibt die aktuell eingestellte Grafik-API zurück (QRhi backend).

Siehe auch setApi().

[protected] QRhiTexture *QRhiWidget::colorTexture() const

Gibt die Textur zurück, die als Farbpuffer für das Widget dient.

Darf nur von initialize() und render() aufgerufen werden.

Anders als der Tiefenschablonenpuffer und QRhiRenderTarget ist diese Textur immer verfügbar und wird von QRhiWidget verwaltet, unabhängig vom Wert von autoRenderTarget.

Hinweis: Wenn sampleCount größer als 1 ist und somit Multisample-Antialiasing aktiviert ist, lautet der Rückgabewert nullptr. Fragen Sie stattdessen QRhiRenderBuffer ab, indem Sie msaaColorBuffer() aufrufen.

Hinweis: Die Größe der zugrundeliegenden Textur und die Anzahl der Samples können auch über den von renderTarget() zurückgegebenen QRhiRenderTarget abgefragt werden. Dies kann bequemer und kompakter sein als die Abfrage über QRhiTexture oder QRhiRenderBuffer, da sie unabhängig davon funktioniert, ob Multisampling verwendet wird oder nicht.

Siehe auch msaaColorBuffer(), depthStencilBuffer(), renderTarget(), und resolveTexture().

[protected] QRhiRenderBuffer *QRhiWidget::depthStencilBuffer() const

Gibt den Tiefenschablonenpuffer zurück, der für das Rendering des Widgets verwendet wird.

Darf nur von initialize() und render() aufgerufen werden.

Nur verfügbar, wenn autoRenderTarget true ist. Andernfalls ist der zurückgegebene Wert nullptr und es obliegt der Neuimplementierung von initialize(), einen Tiefenschablonenpuffer und einen QRhiTextureRenderTarget zu erstellen und zu verwalten.

Siehe auch colorTexture() und renderTarget().

[override virtual protected] bool QRhiWidget::event(QEvent *e)

Reimplements: QWidget::event(QEvent *Event).

[signal] void QRhiWidget::frameSubmitted()

Dieses Signal wird ausgegeben, nachdem das Top-Level-Fenster des Widgets die Komposition beendet und submitted a frame aufgerufen hat.

QImage QRhiWidget::grabFramebuffer() const

Rendert einen neuen Frame, liest den Inhalt der Textur zurück und gibt ihn als QImage zurück.

Wenn ein Fehler auftritt, wird QImage als Null zurückgegeben.

Das zurückgegebene QImage hat ein Format von QImage::Format_RGBA8888, QImage::Format_RGBA16FPx4, QImage::Format_RGBA32FPx4 oder QImage::Format_BGR30, je nach colorBufferFormat().

QRhiWidget kennt den Ansatz des Renderers für Überblendung und Komposition nicht und kann daher nicht wissen, ob die Ausgabe Alpha in den RGB-Farbwerten vormultipliziert hat. Daher werden die Formate _Premultiplied QImage niemals für die zurückgegebenen QImage verwendet, selbst wenn dies angemessen wäre. Es ist dem Aufrufer überlassen, die resultierenden Daten nach eigenem Ermessen umzuinterpretieren.

Hinweis: Diese Funktion kann auch aufgerufen werden, wenn das QRhiWidget nicht zu einer Widget-Hierarchie hinzugefügt wird, die zu einem Fenster der obersten Bildschirm-Ebene gehört. Dies ermöglicht die Erzeugung eines Bildes aus einem 3D-Rendering außerhalb des Bildschirms.

Die Funktion heißt aus Gründen der Konsistenz mit QOpenGLWidget und QQuickWidget grabFramebuffer(). Sie ist nicht die einzige Möglichkeit, CPU-seitige Bilddaten aus dem Inhalt von QRhiWidget zu erhalten: Der Aufruf von QWidget::grab() auf einem QRhiWidget oder einem Vorgänger davon funktioniert ebenfalls (und liefert ein QPixmap). Neben der direkten Arbeit mit QImage besteht ein weiterer Vorteil von grabFramebuffer() darin, dass es etwas leistungsfähiger sein kann, einfach weil es nicht den Rest der QWidget -Infrastruktur durchlaufen muss, sondern sofort das Rendern eines neuen Frames auslösen und dann das Zurücklesen durchführen kann.

Siehe auch setColorBufferFormat().

[virtual protected] void QRhiWidget::initialize(QRhiCommandBuffer *cb)

Wird aufgerufen, wenn das Widget zum ersten Mal initialisiert wird, wenn sich die Größe, das Format oder die Anzahl der Samples der zugehörigen Textur ändert, oder wenn sich QRhi und die Textur aus irgendeinem Grund ändern. Von der Funktion wird erwartet, dass sie die vom Rendering-Code in render() verwendeten Grafikressourcen pflegt (erstellen, wenn noch nicht erstellt, anpassen und neu aufbauen, wenn sich die Größe geändert hat).

Um die Objekte QRhi, QRhiTexture und andere verwandte Objekte abzufragen, rufen Sie rhi(), colorTexture(), depthStencilBuffer() und renderTarget() auf.

Wenn sich die Größe des Widgets ändert, sind das QRhi Objekt, die Farbpuffertextur und die Tiefenschablonenpufferobjekte alle dieselben Instanzen (so dass die Getter dieselben Zeiger zurückgeben) wie zuvor, aber die Farb- und Tiefen-/Schablonenpuffer wurden wahrscheinlich neu erstellt, was bedeutet, dass die size und die zugrunde liegende native Texturressource anders sein können als beim letzten Aufruf.

Reimplementierungen sollten auch darauf vorbereitet sein, dass sich das QRhi Objekt und die Farbpuffertextur zwischen Aufrufen dieser Funktion ändern können. Ein spezieller Fall, in dem die Objekte unterschiedlich sein können, ist die Ausführung von grabFramebuffer() mit einem noch nicht angezeigten Widget und das anschließende Sichtbarmachen des Widgets auf dem Bildschirm innerhalb eines Widgets der obersten Ebene. In diesem Fall wird das Grab mit einem dedizierten QRhi durchgeführt, das dann in den nachfolgenden Aufrufen von initialize() und render() durch das zugehörige QRhi des Top-Level-Fensters ersetzt wird. Ein anderer, häufigerer Fall ist, wenn das Widget reparented wird, so dass es zu einem neuen Fenster der obersten Ebene gehört. In diesem Fall werden die QRhi und alle zugehörigen Ressourcen, die von der QRhiWidget verwaltet werden, beim nachfolgenden Aufruf dieser Funktion andere Instanzen sein als zuvor. Es ist dann wichtig, dass alle bestehenden QRhi Ressourcen, die zuvor von der Unterklasse erstellt wurden, zerstört werden, da sie zu dem vorherigen QRhi gehören, das nicht mehr vom Widget verwendet werden sollte.

Wenn autoRenderTarget true ist, was die Voreinstellung ist, werden eine Tiefenschablone QRhiRenderBuffer und eine QRhiTextureRenderTarget, die mit colorTexture() (oder msaaColorBuffer()) und dem Tiefenschablonenpuffer verbunden sind, automatisch erstellt und verwaltet. Reimplementierungen von initialize() und render() können diese Objekte über depthStencilBuffer() und renderTarget() abfragen. Wenn autoRenderTarget auf false gesetzt wird, werden diese Objekte nicht mehr automatisch erstellt und verwaltet. Stattdessen obliegt es der initialize()-Implementierung, Puffer zu erstellen und das Rendering-Ziel nach eigenem Ermessen einzurichten. Wenn zusätzliche Farb- oder Tiefenschablonenanhänge für das Rendering-Ziel manuell verwaltet werden, müssen ihre Größe und Sampleanzahl immer der Größe und Sampleanzahl von colorTexture() / msaaColorBuffer() entsprechen, da sonst Rendering- oder 3D-API-Validierungsfehler auftreten können.

Es wird erwartet, dass die von der Unterklasse erstellten Grafikressourcen in der Destruktorimplementierung der Unterklasse freigegeben werden.

cb ist die QRhiCommandBuffer für den aktuellen Frame des Widgets. Die Funktion wird aufgerufen, wenn ein Frame aufgezeichnet wird, aber kein aktiver Rendering-Durchgang stattfindet. Der Befehlspuffer wird in erster Linie zur Verfügung gestellt, um das Einreihen von resource updates zu ermöglichen, ohne dass render() aufgeschoben werden muss.

Siehe auch render().

bool QRhiWidget::isDebugLayerEnabled() const

Gibt true zurück, wenn eine Debug- oder Validierungsebene angefordert wird, falls dies für die verwendete Grafik-API zutrifft.

Siehe auch setDebugLayerEnabled().

[protected] QRhiRenderBuffer *QRhiWidget::msaaColorBuffer() const

Gibt den Renderbuffer zurück, der als Multisample-Farbpuffer für das Widget dient.

Darf nur von initialize() und render() aufgerufen werden.

Wenn sampleCount größer als 1 ist und somit Multisample-Antialisierung aktiviert ist, hat der zurückgegebene QRhiRenderBuffer eine passende Sampleanzahl und dient als Farbpuffer. Grafikpipelines, die zum Rendern in diesen Puffer verwendet werden, müssen mit der gleichen Sampleanzahl erstellt werden, und die Sampleanzahl des Tiefenschablonenpuffers muss ebenfalls übereinstimmen. Es wird erwartet, dass der Multisample-Inhalt in die Textur aufgelöst wird, die von resolveTexture() zurückgegeben wird. Wenn autoRenderTarget true ist, wird renderTarget() automatisch für diese Aufgabe eingerichtet, indem msaaColorBuffer() als renderbuffer des Farbanhangs 0 und resolveTexture() als dessen resolveTexture eingerichtet werden.

Wenn MSAA nicht verwendet wird, ist der Rückgabewert nullptr. Verwenden Sie dann stattdessen colorTexture().

Abhängig von der zugrundeliegenden 3D-Grafik-API gibt es möglicherweise keinen praktischen Unterschied zwischen Multisample-Texturen und Farb-Renderbuffern mit einer Sample-Anzahl größer als 1 (QRhi kann einfach beide dem gleichen nativen Ressourcentyp zuordnen). Einige ältere APIs können jedoch zwischen Texturen und Renderbuffern unterscheiden. Um OpenGL ES 3.0 zu unterstützen, wo Multisample-Renderbuffer verfügbar sind, aber Multisample-Texturen nicht, führt QRhiWidget immer MSAA durch, indem ein Multisample QRhiRenderBuffer als Farbanhang verwendet wird (und niemals ein Multisample QRhiTexture).

Hinweis: Die Größe der zugrundeliegenden Textur und die Anzahl der Samples kann auch über die QRhiRenderTarget abgefragt werden, die von renderTarget() zurückgegeben wird. Dies kann bequemer und kompakter sein als die Abfrage über QRhiTexture oder QRhiRenderBuffer, da sie unabhängig davon funktioniert, ob Multisampling verwendet wird oder nicht.

Siehe auch colorTexture(), depthStencilBuffer(), renderTarget(), und resolveTexture().

[override virtual protected] void QRhiWidget::paintEvent(QPaintEvent *e)

Reimplements: QWidget::paintEvent(QPaintEvent *event).

Behandelt Malereignisse.

Der Aufruf von QWidget::update() führt zum Senden eines Malereignisses e und damit zum Aufrufen dieser Funktion. Das Senden des Ereignisses ist asynchron und wird irgendwann nach der Rückkehr von update() erfolgen. Diese Funktion wird dann, nach einer gewissen Vorbereitung, die virtuelle Funktion render() aufrufen, um den Inhalt der zugehörigen Textur von QRhiWidget zu aktualisieren. Das Top-Level-Fenster des Widgets wird dann die Textur mit dem Rest des Fensters zusammensetzen.

[virtual protected] void QRhiWidget::releaseResources()

Wird aufgerufen, wenn die Notwendigkeit besteht, die Grafikressourcen frühzeitig freizugeben.

Dies geschieht normalerweise nicht für ein QRhiWidget, das der Kinderhierarchie eines Widgets der obersten Ebene hinzugefügt wird und dort für den Rest seiner und der Lebensdauer der obersten Ebene verbleibt. Daher besteht in vielen Fällen keine Notwendigkeit, diese Funktion neu zu implementieren, z. B. weil die Anwendung immer nur ein einziges Top-Level-Widget (natives Fenster) hat. Wenn jedoch das Reparenting des Widgets (oder eines Vorgängers davon) involviert ist, wird die Neuimplementierung dieser Funktion in robusten, gut geschriebenen QRhiWidget Unterklassen notwendig werden.

Wenn diese Funktion aufgerufen wird, wird von der Implementierung erwartet, dass sie alle QRhi Ressourcen (QRhiBuffer, QRhiTexture, etc. Objekte) zerstört, ähnlich wie dies im Destruktor erwartet wird. Nulling out, die Verwendung eines Smart Pointers oder das Setzen eines resources-invalid Flags wird ebenfalls erforderlich sein, da initialize() schließlich danach aufgerufen wird. Beachten Sie jedoch, dass es falsch ist, die Freigabe von Ressourcen auf die nachfolgende Funktion initialize() zu verschieben. Wenn diese Funktion aufgerufen wird, muss die Ressource vor der Rückkehr freigegeben werden. Beachten Sie auch, dass die Implementierung dieser Funktion den Destruktor der Klasse (oder Smart Pointer) nicht ersetzt: die Grafikressourcen müssen in beiden weiterhin freigegeben werden.

Ein Beispiel dafür finden Sie im Cube RHI Widget Example. Dort löst die Schaltfläche, die QRhiWidget zwischen einem Kind-Widget (aufgrund eines Eltern-Widgets) und einem Top-Level-Widget (aufgrund eines fehlenden Eltern-Widgets) umschaltet, den Aufruf dieser Funktion aus, da sich das zugehörige Top-Level-Widget, das native Fenster und QRhi alle während der Lebensdauer von QRhiWidget ändern, wobei das zuvor verwendete QRhi zerstört wird, was eine frühzeitige Freigabe der zugehörigen Ressourcen bedeutet, die von dem noch lebenden QRhiWidget verwaltet werden.

Ein weiterer Fall, in dem diese Funktion aufgerufen wird, ist, wenn grabFramebuffer() mit einem QRhiWidget verwendet wird, das nicht zu einem sichtbaren Fenster hinzugefügt wird, d.h. das Rendering wird außerhalb des Bildschirms durchgeführt. Wenn dieses QRhiWidget später sichtbar gemacht oder zu einer sichtbaren Widget-Hierarchie hinzugefügt wird, ändert sich das zugehörige QRhi von dem temporären Rendering, das für das Offscreen-Rendering verwendet wird, zum dedizierten Rendering des Fensters, wodurch diese Funktion ebenfalls ausgelöst wird.

Siehe auch initialize().

[virtual protected] void QRhiWidget::render(QRhiCommandBuffer *cb)

Wird aufgerufen, wenn der Inhalt des Widgets (d. h. der Inhalt der Textur) aktualisiert werden muss.

Es gibt immer mindestens einen Aufruf von initialize(), bevor diese Funktion aufgerufen wird.

Um Aktualisierungen anzufordern, rufen Sie QWidget::update() auf. Der Aufruf von update() innerhalb von render() führt zu einer kontinuierlichen Aktualisierung, die durch vsync gedrosselt wird.

cb ist die QRhiCommandBuffer für den aktuellen Frame des Widgets. Die Funktion wird aufgerufen, während ein Frame aufgezeichnet wird, aber ohne einen aktiven Rendering-Durchgang.

Siehe auch initialize().

[signal] void QRhiWidget::renderFailed()

Dieses Signal wird immer dann ausgegeben, wenn das Widget auf seine Hintergrundtextur rendern soll (entweder aufgrund einer widget update oder aufgrund eines Aufrufs von grabFramebuffer()), aber es gibt keine QRhi für das Widget zu verwenden, wahrscheinlich aufgrund von Problemen im Zusammenhang mit der Grafikkonfiguration.

Dieses Signal kann mehrfach ausgegeben werden, wenn ein Problem auftritt. Gehen Sie nicht davon aus, dass es nur einmal ausgegeben wird. Verbinden Sie sich mit Qt::SingleShotConnection, wenn der Fehlerbehandlungscode nur einmal benachrichtigt werden soll.

[protected] QRhiRenderTarget *QRhiWidget::renderTarget() const

Gibt das Rendering-Zielobjekt zurück, das mit QRhiCommandBuffer::beginPass() in Reimplementierungen von render() verwendet werden muss.

Darf nur von initialize() und render() aufgerufen werden.

Nur verfügbar, wenn autoRenderTarget true ist. Andernfalls ist der zurückgegebene Wert nullptr und es obliegt der Neuimplementierung von initialize(), einen Tiefenschablonenpuffer und einen QRhiTextureRenderTarget zu erstellen und zu verwalten.

Beim Erstellen von graphics pipelines wird ein QRhiRenderPassDescriptor benötigt. Dieser kann aus dem zurückgegebenen QRhiTextureRenderTarget durch Aufruf von renderPassDescriptor() abgefragt werden.

Siehe auch colorTexture() und depthStencilBuffer().

[override virtual protected] void QRhiWidget::resizeEvent(QResizeEvent *e)

Reimplements: QWidget::resizeEvent(QResizeEvent *event).

Verarbeitet Größenänderungsereignisse, die mit dem Parameter e event übergeben werden. Ruft die virtuelle Funktion initialize() auf.

Hinweis: Vermeide es, diese Funktion in abgeleiteten Klassen zu überschreiben. Wenn das nicht möglich ist, stellen Sie sicher, dass auch die Implementierung von QRhiWidget aufgerufen wird. Andernfalls wird die Größe des zugrundeliegenden Texturobjekts und der zugehörigen Ressourcen nicht korrekt angepasst, was zu einem fehlerhaften Rendering führt.

[protected] QRhiTexture *QRhiWidget::resolveTexture() const

Gibt die Nicht-Multisample-Textur zurück, in die der Multisample-Inhalt aufgelöst wird.

Das Ergebnis ist nullptr, wenn Multisample-Antialiasing nicht aktiviert ist.

Darf nur von initialize() und render() aufgerufen werden.

Wenn MSAA aktiviert ist, ist dies die Textur, die mit dem Rest des QWidget Inhalts auf dem Bildschirm zusammengesetzt wird. Das Rendering von QRhiWidget muss jedoch auf das (Multisample) QRhiRenderBuffer abzielen, das von msaaColorBuffer() zurückgegeben wird. Wenn autoRenderTarget true ist, wird dies von dem von renderTarget() zurückgegebenen QRhiRenderTarget übernommen. Andernfalls obliegt es dem Code der Unterklasse, ein Rendering-Zielobjekt mit dem Farbpuffer und den aufgelösten Texturen korrekt zu konfigurieren.

Siehe auch colorTexture().

[protected] QRhi *QRhiWidget::rhi() const

Gibt das aktuelle QRhi Objekt zurück.

Darf nur von initialize() und render() aufgerufen werden.

void QRhiWidget::setApi(QRhiWidget::Api api)

Setzt die zu verwendende Grafik-API und das QRhi Backend auf api.

Warnung: Diese Funktion muss früh genug aufgerufen werden, bevor das Widget zu einer Widget-Hierarchie hinzugefügt und auf dem Bildschirm angezeigt wird. Versuchen Sie zum Beispiel, die Funktion für den Konstruktor der Unterklasse aufzurufen. Wenn sie zu spät aufgerufen wird, hat die Funktion keine Wirkung mehr.

Der Standardwert hängt von der jeweiligen Plattform ab: Metal unter macOS und iOS, Direct 3D 11 unter Windows, ansonsten OpenGL.

Die api kann nur einmal für das Widget und sein Top-Level-Fenster gesetzt werden. Sobald dies geschehen ist und in Kraft tritt, kann das Fenster nur noch dieses API und QRhi Backend zum Rendern verwenden. Der Versuch, einen anderen Wert zu setzen oder einen anderen QRhiWidget mit einem anderen api hinzuzufügen, wird nicht wie erwartet funktionieren.

Siehe auch setColorBufferFormat(), setDebugLayerEnabled(), und api().

[protected] void QRhiWidget::setAutoRenderTarget(bool enabled)

Steuert, ob eine Tiefenschablone QRhiRenderBuffer und eine QRhiTextureRenderTarget automatisch vom Widget erstellt und gepflegt wird. Der Standardwert ist true.

Im automatischen Modus folgen die Größe und die Anzahl der Samples des Tiefenschablonenpuffers den Einstellungen der Farbpuffertextur. Im nicht-automatischen Modus geben renderTarget() und depthStencilBuffer() immer nullptr zurück und es liegt dann an der Implementierung von initialize() in der Anwendung, diese Objekte einzurichten und zu verwalten.

Rufen Sie die Funktion enabled mit dem Wert false frühzeitig auf, z. B. im Konstruktor der abgeleiteten Klasse, um den automatischen Modus zu deaktivieren.

void QRhiWidget::setDebugLayerEnabled(bool enable)

Fordert die Debug- oder Validierungsschicht der zugrunde liegenden Grafik-API an, wenn enable true ist.

Warnung: Diese Funktion muss früh genug aufgerufen werden, bevor das Widget zu einer Widget-Hierarchie hinzugefügt und auf dem Bildschirm angezeigt wird. Rufen Sie zum Beispiel die Funktion für den Konstruktor der Unterklasse auf. Wenn sie zu spät aufgerufen wird, hat die Funktion keine Wirkung mehr.

Gilt für Vulkan und Direct 3D.

Standardmäßig ist diese Funktion deaktiviert.

Siehe auch setApi() und isDebugLayerEnabled().

© 2025 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.