QOpenGLWindow Class
Die Klasse QOpenGLWindow ist eine einfache Unterklasse von QWindow, um OpenGL-Malerei durchzuführen. Mehr...
Kopfzeile: | #include <QOpenGLWindow> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS OpenGL) target_link_libraries(mytarget PRIVATE Qt6::OpenGL) |
qmake: | QT += opengl |
Vererbungen: | QPaintDeviceWindow |
Öffentliche Typen
enum | UpdateBehavior { NoPartialUpdate, PartialUpdateBlit, PartialUpdateBlend } |
Öffentliche Funktionen
QOpenGLWindow(QOpenGLWindow::UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = nullptr) | |
QOpenGLWindow(QOpenGLContext *shareContext, QOpenGLWindow::UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = nullptr) | |
virtual | ~QOpenGLWindow() |
QOpenGLContext * | context() const |
GLuint | defaultFramebufferObject() const |
void | doneCurrent() |
QImage | grabFramebuffer() |
bool | isValid() const |
void | makeCurrent() |
QOpenGLContext * | shareContext() const |
QOpenGLWindow::UpdateBehavior | updateBehavior() const |
Signale
void | frameSwapped() |
Geschützte Funktionen
virtual void | initializeGL() |
virtual void | paintGL() |
virtual void | paintOverGL() |
virtual void | paintUnderGL() |
virtual void | resizeGL(int w, int h) |
Reimplementierte geschützte Funktionen
virtual void | paintEvent(QPaintEvent *event) override |
virtual void | resizeEvent(QResizeEvent *event) override |
Detaillierte Beschreibung
QOpenGLWindow ist ein erweitertes QWindow, das die einfache Erstellung von Fenstern ermöglicht, die OpenGL-Rendering unter Verwendung einer mit QOpenGLWidget kompatiblen API durchführen. Im Gegensatz zu QOpenGLWidget ist QOpenGLWindow nicht vom Widgets-Modul abhängig und bietet eine bessere Leistung.
Eine typische Anwendung wird die Unterklasse QOpenGLWindow bilden und die folgenden virtuellen Funktionen reimplementieren:
- initializeGL() um die Initialisierung der OpenGL-Ressourcen durchzuführen
- resizeGL() um die Transformationsmatrizen und andere von der Fenstergröße abhängige Ressourcen einzurichten
- paintGL() zur Ausgabe von OpenGL-Befehlen oder zum Zeichnen mit QPainter
Um eine Neuzeichnung zu planen, rufen Sie die Funktion update() auf. Beachten Sie, dass dies nicht sofort zu einem Aufruf von paintGL() führt. Wenn Sie update() mehrmals hintereinander aufrufen, ändert sich das Verhalten in keiner Weise.
Dies ist ein Slot, so dass er mit einem QChronoTimer::timeout()-Signal verbunden werden kann, um eine Animation durchzuführen. Beachten Sie jedoch, dass es in der modernen OpenGL-Welt eine viel bessere Wahl ist, sich auf die Synchronisation mit der vertikalen Bildwiederholrate des Displays zu verlassen. Siehe setSwapInterval() für eine Beschreibung des Swap-Intervalls. Mit einem Swap-Intervall von 1
, was auf den meisten Systemen standardmäßig der Fall ist, wird der Aufruf swapBuffers(), der intern von QOpenGLWindow nach jedem Repaint ausgeführt wird, blockieren und auf vsync warten. Das bedeutet, dass jedes Mal, wenn der Tausch abgeschlossen ist, eine Aktualisierung durch den Aufruf von update() erneut geplant werden kann, ohne sich auf Timer zu verlassen.
Um eine bestimmte Konfiguration für den Kontext anzufordern, verwenden Sie setFormat() wie für jede andere QWindow. Dies ermöglicht unter anderem die Abfrage einer bestimmten OpenGL-Version und eines bestimmten Profils oder die Aktivierung von Tiefen- und Schablonenpuffern.
Hinweis: Es liegt an der Anwendung, sicherzustellen, dass Tiefen- und Schablonenpuffer von der zugrunde liegenden Windowing-System-Schnittstelle angefordert werden. Wenn keine Tiefenpuffergröße ungleich Null angefordert wird, gibt es keine Garantie, dass ein Tiefenpuffer verfügbar ist. Infolgedessen kann es vorkommen, dass OpenGL-Operationen im Zusammenhang mit Tiefenprüfungen nicht wie erwartet funktionieren.
Übliche Anforderungen für Tiefen- und Schablonenpuffergrößen sind 24 bzw. 8. Zum Beispiel könnte eine QOpenGLWindow Unterklasse dies in ihrem Konstruktor tun:
QSurfaceFormat format; format.setDepthBufferSize(24); format.setStencilBufferSize(8); setFormat(format);
Im Gegensatz zu QWindow erlaubt QOpenGLWindow das Öffnen eines Painters auf sich selbst und die Durchführung von QPainter-basiertem Zeichnen.
QOpenGLWindow unterstützt mehrere Update-Verhaltensweisen. Die Voreinstellung NoPartialUpdate
entspricht einem regulären, OpenGL-basierten QWindow. Im Gegensatz dazu entsprechen PartialUpdateBlit
und PartialUpdateBlend
eher der Arbeitsweise von QOpenGLWidget, wo immer ein zusätzliches, dediziertes Framebuffer-Objekt vorhanden ist. Diese Modi ermöglichen es, bei jedem Bild nur einen kleineren Bereich neu zu zeichnen und den Rest des Inhalts des vorherigen Bildes beizubehalten, was zu Leistungseinbußen führt. Dies ist nützlich für Anwendungen, die mit QPainter inkrementell rendern, da sie auf diese Weise nicht bei jedem Aufruf von paintGL() den gesamten Fensterinhalt neu zeichnen müssen.
Ähnlich wie QOpenGLWidget unterstützt auch QOpenGLWindow das Qt::AA_ShareOpenGLContexts Attribut. Wenn es aktiviert ist, werden die OpenGL Kontexte aller QOpenGLWindow Instanzen miteinander geteilt. Dies ermöglicht den Zugriff auf die gemeinsam nutzbaren OpenGL-Ressourcen der anderen.
Für weitere Informationen über Grafiken in Qt, siehe Graphics.
Dokumentation der Mitgliedstypen
enum QOpenGLWindow::UpdateBehavior
Diese Aufzählung beschreibt die Aktualisierungsstrategie des QOpenGLWindow.
Konstante | Wert | Beschreibung |
---|---|---|
QOpenGLWindow::NoPartialUpdate | 0 | Gibt an, dass die gesamte Fensteroberfläche bei jeder Aktualisierung neu gezeichnet wird und somit keine zusätzlichen Framebuffer benötigt werden. Dies ist die Einstellung, die in den meisten Fällen verwendet wird und entspricht dem direkten Zeichnen über QWindow. |
QOpenGLWindow::PartialUpdateBlit | 1 | Zeigt an, dass das in paintGL() durchgeführte Zeichnen nicht das gesamte Fenster abdeckt. In diesem Fall wird ein zusätzliches Framebuffer-Objekt unter der Haube erstellt, und das in paintGL() ausgeführte Rendering wird auf diesen Framebuffer ausgerichtet. Dieser Framebuffer wird dann nach jedem Malen auf den Standard-Framebuffer der Fensteroberfläche geblittet. Dies ermöglicht einen QPainter-basierten Zeichencode in paintGL(), der jeweils nur einen kleineren Bereich neu zeichnet, da im Gegensatz zu NoPartialUpdate der vorherige Inhalt erhalten bleibt. |
QOpenGLWindow::PartialUpdateBlend | 2 | Ähnlich wie PartialUpdateBlit, aber anstatt Framebuffer-Blits zu verwenden, wird der Inhalt des zusätzlichen Framebuffers durch Zeichnen eines texturierten Quad mit aktiviertem Blending gerendert. Im Gegensatz zu PartialUpdateBlit erlaubt dies Alpha-Blending-Inhalte und funktioniert auch, wenn der glBlitFramebuffer nicht verfügbar ist. Von der Leistung her ist diese Einstellung wahrscheinlich etwas langsamer als PartialUpdateBlit. |
Dokumentation der Mitgliedsfunktionen
[explicit]
QOpenGLWindow::QOpenGLWindow(QOpenGLWindow::UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = nullptr)
Konstruiert ein neues QOpenGLWindow mit den angegebenen parent und updateBehavior.
Siehe auch QOpenGLWindow::UpdateBehavior.
[explicit]
QOpenGLWindow::QOpenGLWindow(QOpenGLContext *shareContext, QOpenGLWindow::UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = nullptr)
Konstruiert ein neues QOpenGLWindow mit den angegebenen parent und updateBehavior. Der Kontext des QOpenGLWindow wird mit shareContext geteilt.
Siehe auch QOpenGLWindow::UpdateBehavior und shareContext.
[virtual noexcept]
QOpenGLWindow::~QOpenGLWindow()
Zerstört die Instanz QOpenGLWindow und gibt ihre Ressourcen frei.
Der OpenGLWindow-Kontext wird im Destruktor aktuell gemacht, was eine sichere Zerstörung jedes Kindobjekts ermöglicht, das OpenGL-Ressourcen freigeben muss, die zu dem von diesem Fenster bereitgestellten Kontext gehören.
Warnung: Wenn Sie Objekte haben, die OpenGL-Ressourcen umhüllen (wie QOpenGLBuffer, QOpenGLShaderProgram, etc.) als Mitglieder einer QOpenGLWindow Unterklasse, müssen Sie möglicherweise auch einen Aufruf an makeCurrent() in den Destruktor dieser Unterklasse einfügen. Aufgrund der Regeln der C++-Objektzerstörung werden diese Objekte vor dem Aufruf dieser Funktion zerstört (aber nachdem der Destruktor der Unterklasse gelaufen ist), weshalb es für ihre sichere Entsorgung zu spät ist, den OpenGL-Kontext in dieser Funktion aktuell zu machen.
Siehe auch makeCurrent.
QOpenGLContext *QOpenGLWindow::context() const
Rückgabe Die von diesem Fenster verwendete QOpenGLContext oder 0
, wenn es noch nicht initialisiert wurde.
GLuint QOpenGLWindow::defaultFramebufferObject() const
Das Handle des Framebuffer-Objekts, das von diesem Fenster verwendet wird.
Wenn das Aktualisierungsverhalten auf NoPartialUpdate
eingestellt ist, gibt es kein separates Framebuffer-Objekt. In diesem Fall ist der zurückgegebene Wert die ID des Standard-Framebuffers.
Andernfalls der Wert der ID des Framebuffer-Objekts oder 0
, wenn es noch nicht initialisiert wurde.
void QOpenGLWindow::doneCurrent()
Gibt den Kontext frei.
In den meisten Fällen ist es nicht notwendig, diese Funktion aufzurufen, da das Widget beim Aufruf von paintGL() sicherstellt, dass der Kontext richtig gebunden und freigegeben wird.
Siehe auch makeCurrent().
[signal]
void QOpenGLWindow::frameSwapped()
Dieses Signal wird ausgegeben, nachdem die potenziell blockierende buffer swap ausgeführt wurde. Anwendungen, die kontinuierlich und synchron zur vertikalen Aktualisierung neu malen wollen, sollten auf dieses Signal hin ein update() ausgeben. Dies ermöglicht eine viel reibungslosere Erfahrung im Vergleich zur traditionellen Verwendung von Timern.
QImage QOpenGLWindow::grabFramebuffer()
Gibt eine Kopie des Framebuffers zurück.
Hinweis: Dies ist eine potenziell teure Operation, da sie auf glReadPixels() angewiesen ist, um die Pixel zurückzulesen. Dies kann langsam sein und die GPU-Pipeline zum Stillstand bringen.
Hinweis: Wenn die Funktion zusammen mit dem Aktualisierungsverhalten NoPartialUpdate
verwendet wird, enthält das zurückgegebene Bild möglicherweise nicht den gewünschten Inhalt, wenn es aufgerufen wird, nachdem der vordere und der hintere Puffer getauscht wurden (es sei denn, in der zugrunde liegenden Windowing-Systemschnittstelle ist "preserved swap" aktiviert). In diesem Modus liest die Funktion aus dem hinteren Puffer und der Inhalt dieses Puffers stimmt möglicherweise nicht mit dem Inhalt auf dem Bildschirm (dem vorderen Puffer) überein. In diesem Fall ist der einzige Ort, an dem diese Funktion sicher verwendet werden kann, paintGL() oder paintOverGL().
[virtual protected]
void QOpenGLWindow::initializeGL()
Diese virtuelle Funktion wird einmal vor dem ersten Aufruf von paintGL() oder resizeGL() aufgerufen. Reimplementieren Sie sie in einer Unterklasse.
Diese Funktion sollte alle erforderlichen OpenGL-Ressourcen und den Status einrichten.
Es besteht keine Notwendigkeit, makeCurrent() aufzurufen, da dies bereits geschehen ist, wenn diese Funktion aufgerufen wird. Beachten Sie jedoch, dass der Framebuffer, falls der partielle Aktualisierungsmodus verwendet wird, zu diesem Zeitpunkt noch nicht verfügbar ist. Verschieben Sie solche Aufrufe stattdessen auf paintGL().
Siehe auch paintGL() und resizeGL().
bool QOpenGLWindow::isValid() const
Gibt true
zurück, wenn die OpenGL-Ressourcen des Fensters, wie der Kontext, erfolgreich initialisiert wurden. Beachten Sie, dass der Rückgabewert immer false
ist, bis das Fenster offengelegt (angezeigt) wird.
void QOpenGLWindow::makeCurrent()
Bereitet das Rendern von OpenGL-Inhalten für dieses Fenster vor, indem sie den entsprechenden Kontext aktuell macht und das Framebuffer-Objekt, falls vorhanden, an diesen Kontext bindet.
In den meisten Fällen ist es nicht notwendig, diese Funktion aufzurufen, da sie automatisch vor dem Aufruf von paintGL() aufgerufen wird. Sie wird dennoch bereitgestellt, um fortgeschrittene Multi-Thread-Szenarien zu unterstützen, in denen ein anderer Thread als der GUI- oder Haupt-Thread die Oberfläche oder den Framebuffer-Inhalt aktualisieren möchte. Siehe QOpenGLContext für weitere Informationen zu Threading-Problemen.
Diese Funktion kann auch dann aufgerufen werden, wenn das zugrunde liegende Plattformfenster bereits zerstört ist. Das bedeutet, dass es sicher ist, diese Funktion aus dem Destruktor einer QOpenGLWindow Unterklasse aufzurufen. Wenn es kein natives Fenster mehr gibt, wird stattdessen eine Offscreen-Oberfläche verwendet. Dies stellt sicher, dass OpenGL-Ressourcenbereinigungsoperationen im Destruktor immer funktionieren, solange diese Funktion zuerst aufgerufen wird.
Siehe auch QOpenGLContext, context(), paintGL(), und doneCurrent().
[override virtual protected]
void QOpenGLWindow::paintEvent(QPaintEvent *event)
Reimplements: QPaintDeviceWindow::paintEvent(QPaintEvent *event).
Paint event Handler. Ruft paintGL() auf.
Siehe auch paintGL().
[virtual protected]
void QOpenGLWindow::paintGL()
Diese virtuelle Funktion wird immer dann aufgerufen, wenn der Fensterinhalt gezeichnet werden muss. Reimplementieren Sie sie in einer Unterklasse.
Es besteht keine Notwendigkeit, makeCurrent() aufzurufen, da dies bereits geschehen ist, wenn diese Funktion aufgerufen wird.
Vor dem Aufruf dieser Funktion werden der Kontext und der Framebuffer, falls vorhanden, gebunden, und das Ansichtsfenster wird durch einen Aufruf von glViewport() eingerichtet. Es wird kein anderer Status gesetzt und es wird kein Löschen oder Zeichnen durch das Framework durchgeführt.
Hinweis: Bei Verwendung eines partiellen Aktualisierungsverhaltens wie PartialUpdateBlend
wird die Ausgabe des vorherigen paintGL()-Aufrufs beibehalten, und nach dem zusätzlichen Zeichnen beim aktuellen Aufruf der Funktion wird der Inhalt über den Inhalt, der in paintUnderGL() direkt in das Fenster gezeichnet wurde, geblendet oder gemischt.
Siehe auch initializeGL(), resizeGL(), paintUnderGL(), paintOverGL(), und UpdateBehavior.
[virtual protected]
void QOpenGLWindow::paintOverGL()
Diese virtuelle Funktion wird nach jedem Aufruf von paintGL() aufgerufen.
Wenn der Aktualisierungsmodus auf NoPartialUpdate eingestellt ist, gibt es keinen Unterschied zwischen dieser Funktion und paintGL(), das Rendering führt in beiden Fällen zum gleichen Ergebnis.
Wie paintUnderGL() zielt das Rendering in dieser Funktion auf den Standard-Framebuffer des Fensters, unabhängig vom Aktualisierungsverhalten. Sie wird aufgerufen, nachdem paintGL() zurückgekehrt ist und das Blit (PartialUpdateBlit) oder Quad-Drawing (PartialUpdateBlend) durchgeführt wurde.
Siehe auch paintGL(), paintUnderGL(), und UpdateBehavior.
[virtual protected]
void QOpenGLWindow::paintUnderGL()
Die virtuelle Funktion wird vor jedem Aufruf von paintGL() aufgerufen.
Wenn der Aktualisierungsmodus auf NoPartialUpdate
eingestellt ist, gibt es keinen Unterschied zwischen dieser Funktion und paintGL(), das Rendering führt in beiden Fällen zum gleichen Ergebnis.
Der Unterschied wird deutlich, wenn PartialUpdateBlend
verwendet wird, wo ein zusätzliches Framebuffer-Objekt verwendet wird. Dort zielt paintGL() auf dieses zusätzliche Framebuffer-Objekt, dessen Inhalt erhalten bleibt, während paintUnderGL() und paintOverGL() auf den Standard-Framebuffer abzielen, d. h. direkt auf die Fensteroberfläche, deren Inhalt nach jedem angezeigten Frame verloren geht.
Hinweis: Vermeiden Sie es, sich auf diese Funktion zu verlassen, wenn das Aktualisierungsverhalten PartialUpdateBlit
ist. In diesem Modus wird der zusätzliche Framebuffer, der von paintGL() verwendet wird, nach jedem Aufruf von paintGL() in den Standard-Framebuffer eingeblendet, wodurch alle in dieser Funktion erzeugten Zeichnungen überschrieben werden.
Siehe auch paintGL(), paintOverGL(), und UpdateBehavior.
[override virtual protected]
void QOpenGLWindow::resizeEvent(QResizeEvent *event)
Reimplements: QWindow::resizeEvent(QResizeEvent *ev).
Resize event handler. Ruft resizeGL() auf.
Siehe auch resizeGL().
[virtual protected]
void QOpenGLWindow::resizeGL(int w, int h)
Diese virtuelle Funktion wird immer dann aufgerufen, wenn die Größe des Widgets geändert wurde. Reimplementieren Sie sie in einer Unterklasse. Die neue Größe wird in w und h übergeben.
Hinweis: Dies ist lediglich eine Komfortfunktion, um eine API bereitzustellen, die mit QOpenGLWidget kompatibel ist. Anders als bei QOpenGLWidget steht es abgeleiteten Klassen frei, resizeEvent() anstelle dieser Funktion zu überschreiben.
Hinweis: Vermeiden Sie die Ausgabe von OpenGL-Befehlen aus dieser Funktion heraus, da möglicherweise kein aktueller Kontext vorhanden ist, wenn die Funktion aufgerufen wird. Wenn dies nicht vermieden werden kann, rufen Sie makeCurrent() auf.
Hinweis: Das Planen von Aktualisierungen von hier aus ist nicht notwendig. Die Windowing-Systeme senden expose-Ereignisse, die automatisch eine Aktualisierung auslösen.
Siehe auch initializeGL() und paintGL().
QOpenGLContext *QOpenGLWindow::shareContext() const
Gibt die QOpenGLContext zurück, die für die QOpenGLContext dieses Fensters freigegeben werden soll.
QOpenGLWindow::UpdateBehavior QOpenGLWindow::updateBehavior() const
Gibt das Aktualisierungsverhalten für diese QOpenGLWindow zurück.
© 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.