Auf dieser Seite

QOpenGLWidget Class

Die Klasse „QOpenGLWidget“ ist ein Widget zum Rendern von OpenGL-Grafiken. Mehr...

Header: #include <qopenglwidget.h>
CMake: find_package(Qt6 REQUIRED COMPONENTS OpenGLWidgets)
target_link_libraries(mytarget PRIVATE Qt6::OpenGLWidgets)
qmake: QT += openglwidgets
Erbt von: QWidget

Öffentliche Typen

(since 6.5) enum TargetBuffer { LeftBuffer, RightBuffer }
enum UpdateBehavior { NoPartialUpdate, PartialUpdate }

Öffentliche Funktionen

QOpenGLWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags())
virtual ~QOpenGLWidget()
QOpenGLContext *context() const
(since 6.5) QOpenGLWidget::TargetBuffer currentTargetBuffer() const
GLuint defaultFramebufferObject() const
(since 6.5) GLuint defaultFramebufferObject(QOpenGLWidget::TargetBuffer targetBuffer) const
void doneCurrent()
QSurfaceFormat format() const
QImage grabFramebuffer()
(since 6.5) QImage grabFramebuffer(QOpenGLWidget::TargetBuffer targetBuffer)
bool isValid() const
void makeCurrent()
(since 6.5) void makeCurrent(QOpenGLWidget::TargetBuffer targetBuffer)
void setFormat(const QSurfaceFormat &format)
void setTextureFormat(GLenum texFormat)
void setUpdateBehavior(QOpenGLWidget::UpdateBehavior updateBehavior)
GLenum textureFormat() const
QOpenGLWidget::UpdateBehavior updateBehavior() const

Signale

void aboutToCompose()
void aboutToResize()
void frameSwapped()
void resized()

Geschützte Funktionen

virtual void initializeGL()
virtual void paintGL()
virtual void resizeGL(int w, int h)

Neu implementierte geschützte Funktionen

virtual bool event(QEvent *e) override
virtual int metric(QPaintDevice::PaintDeviceMetric metric) const override
virtual QPaintEngine *paintEngine() const override
virtual void paintEvent(QPaintEvent *e) override
virtual QPaintDevice *redirected(QPoint *p) const override
virtual void resizeEvent(QResizeEvent *e) override

Ausführliche Beschreibung

Qt OpenGL Widget bietet Funktionen zur Darstellung von OpenGL-Grafiken, die in eine Qt-Anwendung integriert sind. Die Verwendung ist sehr einfach: Lassen Sie Ihre Klasse von dieser Klasse erben und verwenden Sie die Unterklasse wie jedes andere „ QWidget “, mit dem Unterschied, dass Sie die Wahl zwischen der Verwendung von „ QPainter “ und den Standard-OpenGL-Rendering-Befehlen haben.

QOpenGLWidget stellt drei praktische virtuelle Funktionen bereit, die Sie in Ihrer Unterklasse neu implementieren können, um die typischen OpenGL-Aufgaben auszuführen:

  • paintGL() – Rendert die OpenGL-Szene. Wird immer dann aufgerufen, wenn das Widget aktualisiert werden muss.
  • resizeGL() – Richtet den OpenGL-Viewport, die Projektion usw. ein. Wird aufgerufen, sobald die Größe des Widgets geändert wurde (und auch, wenn es zum ersten Mal angezeigt wird, da alle neu erstellten Widgets automatisch ein Resize-Ereignis erhalten).
  • initializeGL() – Richtet die OpenGL-Ressourcen und den Status ein. Wird einmalig aufgerufen, bevor zum ersten Mal „ resizeGL()“ oder „ paintGL()“ aufgerufen wird.

Wenn Sie eine Neuzeichnung an anderen Stellen als in „ paintGL()“ auslösen müssen (ein typisches Beispiel ist die Verwendung von „ timers “ zur Animation von Szenen), sollten Sie die Funktion „ update()“ des Widgets aufrufen, um eine Aktualisierung zu planen.

Der OpenGL-Rendering-Kontext Ihres Widgets wird aktiv, wenn paintGL(), resizeGL() oder initializeGL() aufgerufen wird. Wenn Sie die Standardfunktionen der OpenGL-API an anderen Stellen aufrufen müssen (z. B. im Konstruktor Ihres Widgets oder in Ihren eigenen Zeichnungsfunktionen), müssen Sie zuvor makeCurrent() aufrufen.

Das gesamte Rendering erfolgt in einem OpenGL-Framebuffer-Objekt. ` makeCurrent()` stellt sicher, dass dieses im Kontext gebunden ist. Beachten Sie dies, wenn Sie im Rendering-Code in ` paintGL()` zusätzliche Framebuffer-Objekte erstellen und binden. Binden Sie den Framebuffer mit der ID 0 niemals erneut. Rufen Sie stattdessen ` defaultFramebufferObject()` auf, um die ID zu erhalten, die gebunden werden soll.

QOpenGLWidget ermöglicht die Verwendung verschiedener OpenGL-Versionen und -Profile, sofern die Plattform dies unterstützt. Legen Sie das gewünschte Format einfach über ` setFormat()` fest. Beachten Sie jedoch, dass bei mehreren `QOpenGLWidget`-Instanzen im selben Fenster alle dasselbe Format verwenden müssen oder zumindest Formate, die die Kontexte nicht unteilbar machen. Um dieses Problem zu umgehen, sollten Sie ` QSurfaceFormat::setDefaultFormat()` anstelle von ` setFormat()` verwenden.

Hinweis: Der Aufruf von ` QSurfaceFormat::setDefaultFormat()` vor der Erstellung der ` QApplication `-Instanz ist auf einigen Plattformen (z. B. macOS) zwingend erforderlich, wenn ein OpenGL-Core-Profile-Kontext angefordert wird. Damit soll sichergestellt werden, dass die gemeinsame Nutzung von Ressourcen zwischen Kontexten weiterhin funktioniert, da alle internen Kontexte mit der richtigen Version und dem richtigen Profil erstellt werden.

Zeichentechniken

Wie oben beschrieben, erstellen Sie eine Unterklasse von `QOpenGLWidget`, um reine 3D-Inhalte wie folgt darzustellen:

  • Implementieren Sie die Funktionen ` initializeGL()` und ` resizeGL()` neu, um den OpenGL-Status einzurichten und eine perspektivische Transformation bereitzustellen.
  • Implementieren Sie ` paintGL()` neu, um die 3D-Szene zu zeichnen, wobei Sie ausschließlich OpenGL-Funktionen aufrufen.

Es ist auch möglich, 2D-Grafiken mithilfe von ` QPainter` auf eine Unterklasse von `QOpenGLWidget` zu zeichnen:

  • Erstellen Sie in ` paintGL()` anstelle der Ausgabe von OpenGL-Befehlen ein ` QPainter `-Objekt zur Verwendung im Widget.
  • Zeichnen Sie Primitive mithilfe der Memberfunktionen von ` QPainter`.
  • Direkte OpenGL-Befehle können weiterhin ausgegeben werden. Sie müssen jedoch sicherstellen, dass diese durch einen Aufruf der Methoden `beginNativePainting()` und `endNativePainting()` des Painters umschlossen sind.

Wenn das Zeichnen ausschließlich über ` QPainter ` erfolgt, ist es auch möglich, das Zeichnen wie bei gewöhnlichen Widgets durchzuführen: durch Neaimplementierung von ` paintEvent()`.

  • Implementieren Sie die Funktion ` paintEvent()` neu.
  • Erstellen Sie ein ` QPainter `-Objekt, das auf das Widget abzielt. Übergeben Sie das Widget entweder an den Konstruktor oder an die Funktion ` QPainter::begin()`.
  • Zeichnen Sie Primitive mithilfe der Member-Funktionen von ` QPainter`.
  • Nach Abschluss des Zeichnungsvorgangs wird die ` QPainter `-Instanz zerstört. Alternativ können Sie ` QPainter::end()` explizit aufrufen.

OpenGL-Funktionsaufrufe, Header und QOpenGLFunctions

Bei OpenGL-Funktionsaufrufen wird dringend empfohlen, einen direkten Aufruf der Funktionen zu vermeiden. Verwenden Sie stattdessen vorzugsweise ` QOpenGLFunctions ` (bei der Erstellung portabler Anwendungen) oder die versionierten Varianten (z. B. ` QOpenGLFunctions_3_2_Core ` und ähnliche, wenn modernes, ausschließlich für den Desktop bestimmtes OpenGL angestrebt wird). Auf diese Weise funktioniert die Anwendung in allen Qt-Build-Konfigurationen korrekt, einschließlich derjenigen, die das dynamische Laden von OpenGL-Implementierungen durchführen. Das bedeutet, dass Anwendungen nicht direkt mit einer GL-Implementierung verknüpft sind und direkte Funktionsaufrufe daher nicht möglich sind.

In ` paintGL()` ist der aktuelle Kontext immer über den Aufruf von ` QOpenGLContext::currentContext()` zugänglich. Aus diesem Kontext heraus kann eine bereits initialisierte, einsatzbereite ` QOpenGLFunctions `-Instanz durch den Aufruf von ` QOpenGLContext::functions()` abgerufen werden. Eine Alternative zum Voranstellen eines Präfixes vor jeden GL-Aufruf besteht darin, von ` QOpenGLFunctions ` zu erben und ` QOpenGLFunctions::initializeOpenGLFunctions()` in ` initializeGL()` aufzurufen.

Was die OpenGL-Header betrifft, ist zu beachten, dass es in den meisten Fällen nicht erforderlich ist, Header wie GL.h direkt einzubinden. Die OpenGL-bezogenen Qt-Header binden qopengl.h ein, das wiederum einen für das jeweilige System geeigneten Header einbindet. Dies kann ein OpenGL ES 3.x- oder 2.0-Header sein, die höchste verfügbare Version oder eine vom System bereitgestellte `gl.h`. Darüber hinaus wird im Rahmen von Qt sowohl für OpenGL als auch für OpenGL ES eine Kopie der Erweiterungs-Header (auf einigen Systemen „glext.h“ genannt) bereitgestellt. Diese werden auf Plattformen, auf denen dies möglich ist, automatisch eingebunden. Das bedeutet, dass Konstanten und Typdefinitionen für Funktionszeiger aus den Erweiterungen ARB, EXT und OES automatisch verfügbar sind.

Code-Beispiele

Für den Einstieg könnte die einfachste Unterklasse von `QOpenGLWidget` wie folgt aussehen:

class MyGLWidget : public QOpenGLWidget
{
public:
    MyGLWidget(QWidget *parent) : QOpenGLWidget(parent) { }

protected:
    void initializeGL() override
    {
        // Set up the rendering context, load shaders and other resources, etc.:
        QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
        f->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        ...
    }

    void resizeGL(int w, int h) override
    {
        // Update projection matrix and other size related settings:
        m_projection.setToIdentity();
        m_projection.perspective(45.0f, w / float(h), 0.01f, 100.0f);
        ...
    }

    void paintGL() override
    {
        // Draw the scene:
        QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
        f->glClear(GL_COLOR_BUFFER_BIT);
        ...
    }

};

Alternativ lässt sich das Voranstellen des Präfixes bei jedem einzelnen OpenGL-Aufruf vermeiden, indem man stattdessen von ` QOpenGLFunctions ` ableitet:

class MyGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
    ...
    void initializeGL() override
    {
        initializeOpenGLFunctions();
        glClearColor(...);
        ...
    }
    ...
};

Um einen Kontext zu erhalten, der mit einer bestimmten OpenGL-Version oder einem bestimmten Profil kompatibel ist, oder um Tiefen- und Stencil-Puffer anzufordern, rufen Sie ` setFormat()` auf:

QOpenGLWidget *widget = new QOpenGLWidget(parent);
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setVersion(3, 2);
format.setProfile(QSurfaceFormat::CoreProfile);
widget->setFormat(format); // must be called before the widget or its parent window gets shown

Hinweis: Es obliegt der Anwendung, sicherzustellen, dass Tiefen- und Stencil-Puffer über die zugrunde liegende Fenster-Systemschnittstelle angefordert werden. Ohne die Angabe einer Tiefenpuffergröße ungleich Null gibt es keine Garantie dafür, dass ein Tiefenpuffer verfügbar ist, was dazu führen kann, dass OpenGL-Operationen im Zusammenhang mit Tiefenprüfungen nicht wie erwartet funktionieren. Häufig verwendete Größenangaben für Tiefen- und Stencil-Puffer sind 24 bzw. 8.

Bei OpenGL 3.0+-Kontexten, bei denen Portabilität keine Rolle spielt, bieten die versionierten Varianten von ` QOpenGLFunctions ` einfachen Zugriff auf alle modernen OpenGL-Funktionen, die in einer bestimmten Version verfügbar sind:

    ...
    void paintGL() override
    {
        QOpenGLFunctions_3_2_Core *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_2_Core>();
        ...
        f->glDrawArraysInstanced(...);
        ...
    }
    ...

Wie oben beschrieben, ist es einfacher und robuster, das gewünschte Format global festzulegen, sodass es während der gesamten Laufzeit der Anwendung für alle Fenster und Kontexte gilt. Nachfolgend finden Sie ein Beispiel hierfür:

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    QSurfaceFormat format;
    format.setDepthBufferSize(24);
    format.setStencilBufferSize(8);
    format.setVersion(3, 2);
    format.setProfile(QSurfaceFormat::CoreProfile);
    QSurfaceFormat::setDefaultFormat(format);

    MyWidget widget;
    widget.show();

    return app.exec();
}

Multisampling

Um Multisampling zu aktivieren, legen Sie die Anzahl der angeforderten Samples im „ QSurfaceFormat “ fest, der an „ setFormat()“ übergeben wird. Auf Systemen, die dies nicht unterstützen, wird die Anforderung möglicherweise ignoriert.

Die Unterstützung von Multisampling setzt die Unterstützung von Multisampling-Renderbuffern und Framebuffer-Blits voraus. Bei OpenGL ES 2.0-Implementierungen ist es wahrscheinlich, dass diese Funktionen nicht vorhanden sind. Das bedeutet, dass Multisampling nicht verfügbar ist. Bei modernen OpenGL-Versionen sowie OpenGL ES 3.0 und höher stellt dies in der Regel kein Problem mehr dar.

Threading

Das Ausführen von Offscreen-Rendering in Worker-Threads, beispielsweise zur Erzeugung von Texturen, die anschließend im GUI-/Haupt-Thread in ` paintGL()` verwendet werden, wird unterstützt, indem die ` QOpenGLContext ` des Widgets freigegeben wird, sodass in jedem Thread zusätzliche Kontexte erstellt werden können, die diese gemeinsam nutzen.

Das direkte Zeichnen in den Framebuffer des QOpenGLWidget außerhalb des GUI-/Haupt-Threads ist möglich, indem ` paintEvent()` so neu implementiert wird, dass es nichts ausführt. Die Thread-Affinität des Kontexts muss über ` QObject::moveToThread()` geändert werden. Danach sind ` makeCurrent()` und ` doneCurrent()` im Worker-Thread nutzbar. Achten Sie darauf, den Kontext anschließend wieder in den GUI-/Haupt-Thread zu verschieben.

Das Auslösen eines Puffertauschs nur für das `QOpenGLWidget` ist nicht möglich, da es dafür keine echte, native Oberfläche auf dem Bildschirm gibt. Es obliegt dem Widget-Stack, die Komposition und Puffertauschvorgänge im GUI-Thread zu verwalten. Wenn ein Thread die Aktualisierung des Framebuffers abgeschlossen hat, rufen Sie ` update()` im GUI-/Hauptthread auf, um die Komposition zu planen.

Es ist besonders darauf zu achten, die Nutzung des Framebuffers zu vermeiden, während der GUI-/Haupt-Thread die Komposition durchführt. Die Signale ` aboutToCompose()` und ` frameSwapped()` werden beim Start und beim Ende der Komposition ausgesendet. Sie werden im GUI-/Haupt-Thread ausgesendet. Das bedeutet, dass bei Verwendung einer direkten Verbindung „ aboutToCompose()“ den GUI-/Haupt-Thread blockieren kann, bis der Worker-Thread sein Rendering abgeschlossen hat. Danach darf der Worker-Thread kein weiteres Rendering durchführen, bis das Signal „ frameSwapped()“ ausgelöst wird. Ist dies nicht akzeptabel, muss der Worker-Thread einen Doppelpufferungsmechanismus implementieren. Dies beinhaltet das Zeichnen unter Verwendung eines alternativen Renderziels, das vollständig vom Thread gesteuert wird, z. B. eines zusätzlichen Framebuffer-Objekts, sowie das Blitten in den Framebuffer des QOpenGLWidget zu einem geeigneten Zeitpunkt.

Kontext-Freigabe

Wenn mehrere `QOpenGLWidgets` als untergeordnete Elemente zum selben Widget der obersten Ebene hinzugefügt werden, teilen sich ihre Kontexte untereinander. Dies gilt nicht für `QOpenGLWidget`-Instanzen, die zu unterschiedlichen Fenstern gehören.

Das bedeutet, dass alle QOpenGLWidgets im selben Fenster auf die gemeinsam nutzbaren Ressourcen der anderen zugreifen können, wie z. B. Texturen, und dass kein zusätzlicher „global share“-Kontext erforderlich ist.

Um die gemeinsame Nutzung zwischen QOpenGLWidget-Instanzen einzurichten, die zu verschiedenen Fenstern gehören, setzen Sie das Anwendungsattribut ` Qt::AA_ShareOpenGLContexts `, bevor Sie ` QApplication` instanziieren. Dies löst die gemeinsame Nutzung zwischen allen QOpenGLWidget-Instanzen ohne weitere Schritte aus.

Es ist auch möglich, zusätzliche ` QOpenGLContext `-Instanzen zu erstellen, die Ressourcen wie Texturen mit dem Kontext des `QOpenGLWidget` gemeinsam nutzen. Übergeben Sie dazu einfach den von ` context()` zurückgegebenen Zeiger an ` QOpenGLContext::setShareContext()`, bevor Sie ` QOpenGLContext::create()` aufrufen. Der resultierende Kontext kann auch in einem anderen Thread verwendet werden, was die Thread-basierte Erzeugung von Texturen und asynchrone Textur-Uploads ermöglicht.

Beachten Sie, dass QOpenGLWidget eine standardkonforme Implementierung der Ressourcenfreigabe seitens der zugrunde liegenden Grafiktreiber erwartet. Beispielsweise haben einige Treiber, insbesondere für mobile und eingebettete Hardware, Probleme bei der Einrichtung der Freigabe zwischen einem bestehenden Kontext und anderen, die später erstellt werden. Andere Treiber verhalten sich möglicherweise unerwartet, wenn versucht wird, gemeinsam genutzte Ressourcen zwischen verschiedenen Threads zu nutzen.

Initialisierung und Bereinigung von Ressourcen

Der mit dem QOpenGLWidget verbundene OpenGL-Kontext ist garantiert aktuell, sobald „ initializeGL()“ und „ paintGL()“ aufgerufen werden. Versuchen Sie nicht, OpenGL-Ressourcen zu erstellen, bevor „ initializeGL()“ aufgerufen wurde. So schlägt beispielsweise der Versuch, Shader zu kompilieren, Vertex-Buffer-Objekte zu initialisieren oder Texturdaten hochzuladen, fehl, wenn dies im Konstruktor einer Unterklasse erfolgt. Diese Operationen müssen auf ` initializeGL()` verschoben werden. Einige der Qt OpenGL-Hilfsklassen, wie ` QOpenGLBuffer ` oder ` QOpenGLVertexArrayObject`, weisen ein entsprechendes verzögertes Verhalten auf: Sie können ohne Kontext instanziiert werden, doch die gesamte Initialisierung wird bis zum Aufruf von ` create()` oder einer ähnlichen Funktion verschoben. Das bedeutet, dass sie als normale (nicht auf Zeiger verweisende) Membervariablen in einer Unterklasse von `QOpenGLWidget` verwendet werden können, die Funktion ` create()` oder eine ähnliche Funktion jedoch nur von ` initializeGL()` aus aufgerufen werden kann. Beachten Sie jedoch, dass nicht alle Klassen auf diese Weise konzipiert sind. Im Zweifelsfall sollten Sie die Membervariable als Zeiger definieren und die Instanz dynamisch in ` initializeGL()` bzw. im Destruktor anlegen und löschen.

Um die Ressourcen freizugeben, muss zudem der Kontext aktuell sein. Daher wird erwartet, dass Destruktoren, die eine solche Bereinigung durchführen, zunächst ` makeCurrent()` aufrufen, bevor sie mit der Zerstörung von OpenGL-Ressourcen oder Wrappern fortfahren. Vermeiden Sie eine verzögerte Löschung über ` deleteLater()` oder den Eltern-Kind-Mechanismus von ` QObject`. Es gibt keine Garantie dafür, dass der richtige Kontext zum Zeitpunkt der tatsächlichen Zerstörung der betreffenden Instanz aktuell ist.

Eine typische Unterklasse sieht daher hinsichtlich der Initialisierung und Löschung von Ressourcen oft wie folgt aus:

class MyGLWidget : public QOpenGLWidget
{
    ...

private:
    QOpenGLVertexArrayObject m_vao;
    QOpenGLBuffer m_vbo;
    QOpenGLShaderProgram *m_program;
    QOpenGLShader *m_shader;
    QOpenGLTexture *m_texture;
};

MyGLWidget::MyGLWidget()
    : m_program(0), m_shader(0), m_texture(0)
{
    // No OpenGL resource initialization is done here.
}

MyGLWidget::~MyGLWidget()
{
    // Make sure the context is current and then explicitly
    // destroy all underlying OpenGL resources.
    makeCurrent();

    delete m_texture;
    delete m_shader;
    delete m_program;

    m_vbo.destroy();
    m_vao.destroy();

    doneCurrent();
}

void MyGLWidget::initializeGL()
{
    m_vao.create();
    if (m_vao.isCreated())
        m_vao.bind();

    m_vbo.create();
    m_vbo.bind();
    m_vbo.allocate(...);

    m_texture = new QOpenGLTexture(QImage(...));

    m_shader = new QOpenGLShader(...);
    m_program = new QOpenGLShaderProgram(...);

    ...
}

Dies funktioniert in den meisten Fällen, ist jedoch als generische Lösung nicht ganz ideal. Wenn das Widget einem neuen übergeordneten Element zugeordnet wird, sodass es in einem völlig anderen Fenster der obersten Ebene landet, ist eine zusätzliche Maßnahme erforderlich: Durch die Anbindung an das Signal „ aboutToBeDestroyed()“ von ` QOpenGLContext` kann die Bereinigung immer dann durchgeführt werden, wenn der OpenGL-Kontext freigegeben werden soll.

Hinweis: Für Widgets, die während ihrer Lebensdauer mehrfach das zugehörige Top-Level-Fenster wechseln, ist ein kombinierter Bereinigungsansatz, wie im folgenden Codeausschnitt gezeigt, unerlässlich. Immer wenn das Widget oder eines seiner übergeordneten Elemente neu zugeordnet wird, sodass sich das Top-Level-Fenster ändert, wird der zugehörige Kontext des Widgets zerstört und ein neuer erstellt. Darauf folgt ein Aufruf von ` initializeGL()`, bei dem alle OpenGL-Ressourcen neu initialisiert werden müssen. Aus diesem Grund besteht die einzige Möglichkeit, eine ordnungsgemäße Bereinigung durchzuführen, darin, eine Verbindung zum Signal `aboutToBeDestroyed()` des Kontexts herzustellen. Beachten Sie, dass der betreffende Kontext zum Zeitpunkt der Signalauslösung möglicherweise nicht der aktuelle ist. Daher empfiehlt es sich, im verbundenen Slot ` makeCurrent()` aufzurufen. Zusätzlich müssen dieselben Aufräumschritte im Destruktor der abgeleiteten Klasse durchgeführt werden, da der mit dem Signal verbundene Slot oder das Lambda möglicherweise nicht aufgerufen wird, wenn das Widget zerstört wird.

MyGLWidget::~MyGLWidget()
{
    cleanup();
}

void MyGLWidget::initializeGL()
{
    ...
    connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &MyGLWidget::cleanup);
}

void MyGLWidget::cleanup()
{
    makeCurrent();
    delete m_texture;
    m_texture = 0;
    ...
    doneCurrent();
    disconnect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &MyGLWidget::cleanup);
}

Hinweis: Wenn „ Qt::AA_ShareOpenGLContexts “ gesetzt ist, ändert sich der Kontext des Widgets niemals, auch nicht bei einer Umordnung, da die dem Widget zugeordnete Textur auch vom Kontext der neuen obersten Ebene aus zugänglich ist. Daher ist es bei gesetztem Flag nicht zwingend erforderlich, auf das Signal „aboutToBeDestroyed()“ des Kontexts zu reagieren.

Eine ordnungsgemäße Bereinigung ist aufgrund der gemeinsamen Nutzung von Kontexten besonders wichtig. Auch wenn der mit jedem `QOpenGLWidget` verknüpfte Kontext zusammen mit dem `QOpenGLWidget` zerstört wird, bleiben die gemeinsam nutzbaren Ressourcen in diesem Kontext, wie z. B. Texturen, so lange gültig, bis das oberste Fenster, in dem sich das `QOpenGLWidget` befand, zerstört wird. Zudem können Einstellungen wie „ Qt::AA_ShareOpenGLContexts “ und einige Qt-Module einen noch größeren Umfang für die gemeinsame Nutzung von Kontexten auslösen, was möglicherweise dazu führt, dass die betreffenden Ressourcen während der gesamten Laufzeit der Anwendung erhalten bleiben. Daher ist es am sichersten und zuverlässigsten, stets eine explizite Bereinigung aller im QOpenGLWidget verwendeten Ressourcen und Ressourcen-Wrapper durchzuführen.

Einschränkungen und weitere Überlegungen

Das Platzieren anderer Widgets darunter und das transparent Machen des QOpenGLWidgets führt nicht zu den erwarteten Ergebnissen: Die darunter liegenden Widgets sind nicht sichtbar. Dies liegt daran, dass das QOpenGLWidget in der Praxis vor allen anderen regulären, nicht-OpenGL-basierten Widgets gezeichnet wird, sodass durchsichtige Lösungen nicht realisierbar sind. Andere Layout-Varianten, wie beispielsweise Widgets, die über dem QOpenGLWidget liegen, funktionieren wie erwartet.

Wenn es unbedingt erforderlich ist, lässt sich diese Einschränkung durch Setzen des Attributs „ Qt::WA_AlwaysStackOnTop “ am QOpenGLWidget umgehen. Beachten Sie jedoch, dass dies die Stapelreihenfolge aufhebt; so ist es beispielsweise nicht mehr möglich, andere Widgets über dem QOpenGLWidget anzuordnen. Daher sollte diese Option nur in Situationen verwendet werden, in denen ein halbtransparentes QOpenGLWidget erforderlich ist, unter dem andere Widgets sichtbar sind.

Beachten Sie, dass dies nicht gilt, wenn sich keine anderen Widgets darunter befinden und ein halbtransparentes Fenster gewünscht ist. In diesem Fall reicht der herkömmliche Ansatz aus, bei dem „ Qt::WA_TranslucentBackground “ für das oberste Fenster gesetzt wird. Beachten Sie, dass, wenn die transparenten Bereiche nur im `QOpenGLWidget` gewünscht sind, ` Qt::WA_NoSystemBackground ` nach dem Aktivieren von ` Qt::WA_TranslucentBackground` wieder auf ` false ` zurückgesetzt werden muss. Zusätzlich kann es je nach System erforderlich sein, über ` setFormat()` einen Alphakanal für den Kontext des `QOpenGLWidget` anzufordern.

QOpenGLWidget unterstützt mehrere Aktualisierungsmodi, genau wie QOpenGLWindow. Im „preserved“-Modus stehen die gerenderten Inhalte des vorherigen Aufrufs von paintGL() im nächsten Aufruf zur Verfügung, was ein inkrementelles Rendern ermöglicht. Im „non-preserved“-Modus gehen die Inhalte verloren, und von den Implementierungen von paintGL() wird erwartet, dass sie die gesamte Ansicht neu zeichnen.

Vor Qt 5.5 bestand das Standardverhalten von `QOpenGLWidget` darin, die gerenderten Inhalte zwischen den Aufrufen von ` paintGL()` beizubehalten. Seit Qt 5.5 ist das Standardverhalten der „Non-Preserved“-Modus, da dies eine bessere Leistung bietet und die meisten Anwendungen keinen Bedarf an den vorherigen Inhalten haben. Dies entspricht zudem der Semantik eines OpenGL-basierten „ QWindow “ und stimmt mit dem Standardverhalten von „ QOpenGLWindow “ überein, da die Farb- und Zusatzpuffer bei jedem Frame ungültig gemacht werden. Um das Verhalten mit Beibehaltung der Inhalte wiederherzustellen, rufen Sie „ setUpdateBehavior()“ mit „ PartialUpdate “ auf.

Hinweis: Beim dynamischen Hinzufügen eines `QOpenGLWidget` zu einer Widget-Hierarchie, z. B. durch das Einfügen eines neuen `QOpenGLWidget` als untergeordnetes Element eines Widgets, dessen übergeordnetes Widget der obersten Ebene bereits auf dem Bildschirm angezeigt wird, kann das zugehörige native Fenster implizit zerstört und neu erstellt werden, wenn das `QOpenGLWidget` das erste seiner Art innerhalb dieses Fensters ist. Dies liegt daran, dass sich der Fenstertyp von „ RasterSurface “ zu „ OpenGLSurface “ ändert, was plattformspezifische Auswirkungen hat. Dieses Verhalten ist neu in Qt 6.4.

Sobald ein QOpenGLWidget zu einer Widget-Hierarchie hinzugefügt wird, wird der Inhalt des Top-Level-Fensters über OpenGL-basiertes Rendering ausgegeben. Andere Widgets als das QOpenGLWidget zeichnen ihren Inhalt weiterhin mit einem softwarebasierten Painter, doch die endgültige Komposition erfolgt über die 3D-API.

Hinweis: Die Darstellung eines `QOpenGLWidget` erfordert aufgrund der Funktionsweise der Komposition mit anderen auf „ QWidget “ basierenden Inhalten einen Alphakanal im Backing-Store des zugehörigen obersten Fensters. Ist kein Alphakanal vorhanden, ist der vom QOpenGLWidget gerenderte Inhalt nicht sichtbar. Dies kann insbesondere unter Linux/X11 bei Remote-Display-Konfigurationen (z. B. mit Xvnc) relevant werden, wenn eine Farbtiefe von weniger als 24 verwendet wird. Beispielsweise entspricht eine Farbtiefe von 16 in der Regel der Verwendung eines Backing-Store-Bildes im Format „ QImage::Format_RGB16 “ (RGB565), wodurch kein Platz für einen Alphakanal bleibt. Sollten daher Probleme auftreten, den Inhalt eines QOpenGLWidgets korrekt mit anderen Widgets im Fenster zu kombinieren, stellen Sie sicher, dass der Server (z. B. vncserver) mit einer Farbtiefe von 24 oder 32 Bit anstelle von 16 Bit konfiguriert ist.

Alternativen

Das Hinzufügen eines QOpenGLWidget zu einem Fenster aktiviert das OpenGL-basierte Compositing für das gesamte Fenster. In einigen Sonderfällen ist dies möglicherweise nicht ideal, und das alte Verhalten im Stil von QGLWidget mit einem separaten, nativen untergeordneten Fenster ist wünschenswert. Desktop-Anwendungen, die die Einschränkungen dieses Ansatzes kennen (beispielsweise in Bezug auf Überlappungen, Transparenz, Scroll-Ansichten und MDI-Bereiche), können ` QOpenGLWindow ` in Verbindung mit ` QWidget::createWindowContainer()` verwenden. Dies ist eine moderne Alternative zu `QGLWidget` und aufgrund des Wegfalls des zusätzlichen Compositing-Schritts schneller als `QOpenGLWidget`. Es wird dringend empfohlen, die Verwendung dieses Ansatzes auf Fälle zu beschränken, in denen es keine andere Wahl gibt. Beachten Sie, dass diese Option für die meisten eingebetteten und mobilen Plattformen nicht geeignet ist und auch auf bestimmten Desktop-Plattformen (z. B. macOS) bekanntermaßen Probleme verursacht. Die stabile, plattformübergreifende Lösung ist immer QOpenGLWidget.

Stereoskopisches Rendering

Ab Version 6.5 unterstützt QOpenGLWidget das stereoskopische Rendering. Um es zu aktivieren, setzen Sie das Flag „ QSurfaceFormat::StereoBuffers “ global vor der Erstellung des Fensters mithilfe von `QSurfaceFormat::SetDefaultFormat()`.

Hinweis: Die Verwendung von ` setFormat()` funktioniert aufgrund der internen Handhabung des Flags nicht unbedingt.

Dadurch wird „ paintGL()“ in jedem Frame zweimal aufgerufen, einmal für jeden „ QOpenGLWidget::TargetBuffer “. Rufen Sie in „ paintGL()“ die Funktion „ currentTargetBuffer()“ auf, um abzufragen, in welchen Puffer gerade gezeichnet wird.

Hinweis: Um mehr Kontrolle über den linken und den rechten Farbpufferzu erhalten , sollten Sie stattdessen die Verwendung von ` QOpenGLWindow ` + ` QWidget::createWindowContainer()` in Betracht ziehen.

Hinweis: Diese Art des 3D-Renderings stellt bestimmte Hardwareanforderungen, z. B. muss die Grafikkarte für Stereo-Unterstützung konfiguriert sein.

OpenGL ist eine Marke von Silicon Graphics, Inc. in den Vereinigten Staaten und anderen Ländern.

Siehe auch QOpenGLFunctions, QOpenGLWindow, Qt::AA_ShareOpenGLContexts und UpdateBehavior.

Dokumentation zu Mitgliedstypen

[since 6.5] enum QOpenGLWidget::TargetBuffer

Legt den zu verwendenden Puffer fest, wenn das stereoskopische Rendering aktiviert ist. Dies wird durch die Einstellung „ QSurfaceFormat::StereoBuffers “ umgeschaltet.

Hinweis: „LeftBuffer“ ist immer der Standardwert und wird als Ausweichwert verwendet, wenn die stereoskopische Darstellung deaktiviert ist oder vom Grafiktreiber nicht unterstützt wird.

KonstanteWert
QOpenGLWidget::LeftBuffer0
QOpenGLWidget::RightBuffer1

Diese Enumeration wurde in Qt 6.5 eingeführt.

enum QOpenGLWidget::UpdateBehavior

Diese Enumeration beschreibt die Aktualisierungssemantik von „ QOpenGLWidget “.

KonstanteWertBeschreibung
QOpenGLWidget::NoPartialUpdate0QOpenGLWidget verwirft den Inhalt des Farbpuffers und der Zusatzpuffer, nachdem das „ QOpenGLWidget “ auf dem Bildschirm gerendert wurde. Dies entspricht dem Verhalten, das beim Aufruf von „ QOpenGLContext::swapBuffers “ mit einem standardmäßig OpenGL-fähigen „ QWindow “ als Argument zu erwarten ist. „NoPartialUpdate“ kann auf bestimmten Hardwarearchitekturen, wie sie im Mobil- und Embedded-Bereich üblich sind, Leistungsvorteile bieten, wenn ein Framebuffer-Objekt als Rendering-Ziel verwendet wird. Das Framebuffer-Objekt wird zwischen den Frames mit `glInvalidateFramebuffer` (sofern unterstützt) oder, als Fallback, mit `glDiscardFramebufferEXT` (sofern unterstützt) oder einem Aufruf von `glClear` ungültig gemacht.
QOpenGLWidget::PartialUpdate1Der Farbpuffer und die Zusatzpuffer des Framebuffer-Objekts werden zwischen den Frames nicht ungültig gemacht.

Siehe auch „ updateBehavior()“ und „ setUpdateBehavior()“.

Dokumentation der Mitgliedsfunktionen

[explicit] QOpenGLWidget::QOpenGLWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags())

Erstellt ein Widget, das ein untergeordnetes Element von „ parent “ ist, wobei die Widget-Flags auf „ f “ gesetzt sind.

[virtual noexcept] QOpenGLWidget::~QOpenGLWidget()

Löscht die Instanz von „ QOpenGLWidget “ und gibt deren Ressourcen frei.

Der Kontext des „ QOpenGLWidget “ wird im Destruktor als aktueller Kontext festgelegt, wodurch eine sichere Zerstörung aller untergeordneten Objekte ermöglicht wird, die möglicherweise OpenGL-Ressourcen freigeben müssen, die zu dem von diesem Widget bereitgestellten Kontext gehören.

Warnung: Wenn Sie Objekte, die OpenGL-Ressourcen verpacken (wie z. B. ` QOpenGLBuffer`, ` QOpenGLShaderProgram` usw.), als Mitglieder einer `OpenGLWidget`-Unterklasse haben, müssen Sie möglicherweise auch im Destruktor dieser Unterklasse einen Aufruf von ` makeCurrent()` hinzufügen. Aufgrund der Regeln zur Objektzerstörung in C++ werden diese Objekte vor dem Aufruf dieser Funktion zerstört (jedoch nachdem der Destruktor der Unterklasse ausgeführt wurde), sodass die Aktivierung des OpenGL-Kontexts in dieser Funktion zu spät erfolgt, um eine sichere Entsorgung dieser Objekte zu gewährleisten.

Siehe auch makeCurrent.

[signal] void QOpenGLWidget::aboutToCompose()

Dieses Signal wird ausgelöst, wenn das oberste Fenster des Widgets im Begriff ist, die Texturen seiner untergeordneten Elemente „ QOpenGLWidget “ und der anderen Widgets zusammenzusetzen.

[signal] void QOpenGLWidget::aboutToResize()

Dieses Signal wird ausgelöst, wenn sich die Größe des Widgets ändert und das Framebuffer-Objekt daher neu erstellt wird.

QOpenGLContext *QOpenGLWidget::context() const

Gibt das von diesem Widget verwendete „ QOpenGLContext “ zurück oder „ 0 “, falls es noch nicht initialisiert wurde.

Hinweis: Der Kontext und das vom Widget verwendete Framebuffer-Objekt ändern sich, wenn das Widget über ` setParent()` einem anderen Elternelement zugeordnet wird.

Siehe auch QOpenGLContext::setShareContext() und defaultFramebufferObject().

[since 6.5] QOpenGLWidget::TargetBuffer QOpenGLWidget::currentTargetBuffer() const

Gibt den derzeit aktiven Zielpuffer zurück. Standardmäßig ist dies der linke Puffer; der rechte Puffer wird nur verwendet, wenn „ QSurfaceFormat::StereoBuffers “ aktiviert ist. Wenn das stereoskopische Rendering aktiviert ist, kann dies über ` paintGL()` abgefragt werden, um festzustellen, welcher Puffer derzeit verwendet wird. ` paintGL()` wird zweimal aufgerufen, einmal für jedes Ziel.

Diese Funktion wurde in Qt 6.5 eingeführt.

Siehe auch paintGL().

GLuint QOpenGLWidget::defaultFramebufferObject() const

Gibt das Framebuffer-Objekt-Handle zurück oder „ 0 “, falls es noch nicht initialisiert wurde.

Hinweis: Das Framebuffer-Objekt gehört zu dem von ` context()` zurückgegebenen Kontext und ist möglicherweise von anderen Kontexten aus nicht zugänglich.

Hinweis: Der Kontext und das vom Widget verwendete Framebuffer-Objekt ändern sich, wenn das Widget über ` setParent()` einem neuen Elternelement zugeordnet wird. Außerdem ändert sich das Framebuffer-Objekt bei jeder Größenänderung.

Siehe auch ` context()`.

[since 6.5] GLuint QOpenGLWidget::defaultFramebufferObject(QOpenGLWidget::TargetBuffer targetBuffer) const

Gibt das Framebuffer-Objekt-Handle des angegebenen Zielpuffers zurück oder 0, falls dieser noch nicht initialisiert wurde.

Der Aufruf dieser Überladung ist nur dann sinnvoll, wenn „ QSurfaceFormat::StereoBuffers “ aktiviert ist und von der Hardware unterstützt wird. Ist dies nicht der Fall, gibt diese Methode den Standardpuffer zurück.

Hinweis: Das Framebuffer-Objekt gehört zu dem von ` context()` zurückgegebenen Kontext und ist möglicherweise von anderen Kontexten aus nicht zugänglich. Der Kontext und das vom Widget verwendete Framebuffer-Objekt ändern sich, wenn das Widget über ` setParent()` einem neuen Elternelement zugeordnet wird. Außerdem ändert sich das Framebuffer-Objekt bei jeder Größenänderung.

Diese Funktion wurde in Qt 6.5 eingeführt.

Siehe auch ` context()`.

void QOpenGLWidget::doneCurrent()

Gibt den Kontext frei.

In den meisten Fällen ist es nicht notwendig, diese Funktion aufzurufen, da das Widget sicherstellt, dass der Kontext beim Aufruf von ` paintGL()` ordnungsgemäß gebunden und freigegeben wird.

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

Umsetzt: ` QWidget::event(QEvent *event)`.

QSurfaceFormat QOpenGLWidget::format() const

Gibt das Kontext- und Oberflächenformat zurück, das von diesem Widget und seinem obersten Fenster verwendet wird.

Nachdem das Widget und sein oberstes Fenster erstellt, in der Größe angepasst und angezeigt wurden, gibt diese Funktion das tatsächliche Format des Kontexts zurück. Dieses kann vom angeforderten Format abweichen, wenn die Plattform die Anforderung nicht erfüllen konnte. Es ist auch möglich, größere Farbpuffergrößen als angefordert zu erhalten.

Wenn das Fenster des Widgets und die zugehörigen OpenGL-Ressourcen noch nicht initialisiert sind, ist der Rückgabewert das Format, das über ` setFormat()` festgelegt wurde.

Siehe auch setFormat() und context().

[signal] void QOpenGLWidget::frameSwapped()

Dieses Signal wird ausgelöst, nachdem das oberste Fenster des Widgets die Komposition abgeschlossen hat und von seinem möglicherweise blockierenden Aufruf von ` QOpenGLContext::swapBuffers()` zurückgekehrt ist.

QImage QOpenGLWidget::grabFramebuffer()

Rendert und gibt ein 32-Bit-RGB-Bild des Framebuffers zurück.

Hinweis: Dies ist ein potenziell rechenintensiver Vorgang, da er auf glReadPixels() zurückgreift, um die Pixel auszulesen. Dies kann langsam sein und die GPU-Pipeline blockieren.

[since 6.5] QImage QOpenGLWidget::grabFramebuffer(QOpenGLWidget::TargetBuffer targetBuffer)

Rendert und gibt ein 32-Bit-RGB-Bild des Framebuffers des angegebenen Zielpuffers zurück. Der Aufruf dieser Überladung ist nur dann sinnvoll, wenn „ QSurfaceFormat::StereoBuffers “ aktiviert ist. Wird der Framebuffer des richtigen Zielpuffers abgerufen, wird das Standardbild zurückgegeben, wenn das stereoskopische Rendering deaktiviert ist oder von der Hardware nicht unterstützt wird.

Hinweis: Dies ist eine potenziell rechenintensive Operation, da sie zum Zurücklesen der Pixel auf `glReadPixels()` zurückgreift. Dies kann langsam sein und die GPU-Pipeline blockieren.

Diese Funktion wurde in Qt 6.5 eingeführt.

[virtual protected] void QOpenGLWidget::initializeGL()

Diese virtuelle Funktion wird einmal vor dem ersten Aufruf von ` paintGL()` oder ` resizeGL()` aufgerufen. Implementieren Sie sie in einer Unterklasse neu.

Diese Funktion sollte alle erforderlichen OpenGL-Ressourcen einrichten.

Es ist nicht erforderlich, ` makeCurrent()` aufzurufen, da dies bereits beim Aufruf dieser Funktion geschehen ist. Beachten Sie jedoch, dass der Framebuffer zu diesem Zeitpunkt noch nicht verfügbar ist; vermeiden Sie daher, von hier aus Zeichenaufrufe auszuführen. Verschieben Sie solche Aufrufe stattdessen auf ` paintGL()`.

Siehe auch paintGL() und resizeGL().

bool QOpenGLWidget::isValid() const

Gibt „true“ zurück, wenn das Widget und die OpenGL-Ressourcen, wie beispielsweise der Kontext, erfolgreich initialisiert wurden. Beachten Sie, dass der Rückgabewert immer „false“ ist, bis das Widget angezeigt wird.

void QOpenGLWidget::makeCurrent()

Bereitet die Darstellung von OpenGL-Inhalten für dieses Widget vor, indem der entsprechende Kontext als aktueller Kontext festgelegt und das Framebuffer-Objekt in diesem Kontext eingebunden wird.

In den meisten Fällen ist es nicht erforderlich, diese Funktion aufzurufen, da sie automatisch vor dem Aufruf von ` paintGL()` aufgerufen wird.

Siehe auch „ context()“, „ paintGL()“ und „ doneCurrent()“.

[since 6.5] void QOpenGLWidget::makeCurrent(QOpenGLWidget::TargetBuffer targetBuffer)

Bereitet die Darstellung von OpenGL-Inhalten für dieses Widget vor, indem der Kontext für den übergebenen Puffer als aktueller Kontext festgelegt und das Framebuffer-Objekt in diesem Kontext gebunden wird.

Hinweis: Der Aufrufdieser Funktion ist nur sinnvoll, wenn das stereoskopische Rendering aktiviert ist. Wird der rechte Puffer angefordert, während es deaktiviert ist, geschieht nichts.

In den meisten Fällen ist es nicht erforderlich, diese Funktion aufzurufen, da sie automatisch vor dem Aufruf von ` paintGL()` aufgerufen wird.

Diese Funktion wurde in Qt 6.5 eingeführt.

Siehe auch „ context()“, „ paintGL()“ und „ doneCurrent()“.

[override virtual protected] int QOpenGLWidget::metric(QPaintDevice::PaintDeviceMetric metric) const

Implementiert: ` QWidget::metric(QPaintDevice::PaintDeviceMetric m) const`.

[override virtual protected] QPaintEngine *QOpenGLWidget::paintEngine() const

Implementiert: ` QWidget::paintEngine()` const.

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

Umsetzt: ` QWidget::paintEvent` (`QPaintEvent *event`).

Behandelt Zeichenereignisse.

Der Aufruf von ` QWidget::update()` führt dazu, dass ein Zeichenereignis an ` e` gesendet und somit diese Funktion aufgerufen wird. (Hinweis: Dies erfolgt asynchron und geschieht zu einem beliebigen Zeitpunkt nach der Rückkehr aus ` update()`. Diese Funktion ruft dann nach einigen Vorbereitungen die virtuelle Funktion ` paintGL()` auf, um den Inhalt des Framebuffers des ` QOpenGLWidget` zu aktualisieren. Das oberste Fenster des Widgets führt anschließend eine Komposition der Textur des Framebuffers mit dem Rest des Fensters durch.

[virtual protected] void QOpenGLWidget::paintGL()

Diese virtuelle Funktion wird immer dann aufgerufen, wenn das Widget gezeichnet werden muss. Implementieren Sie sie in einer Unterklasse neu.

Es ist nicht erforderlich, ` makeCurrent()` aufzurufen, da dies bereits beim Aufruf dieser Funktion geschehen ist.

Vor dem Aufruf dieser Funktion werden der Kontext und der Framebuffer gebunden, und der Viewport wird durch einen Aufruf von `glViewport()` eingerichtet. Es wird kein weiterer Status gesetzt, und das Framework führt weder ein Löschen noch ein Zeichnen durch.

Die Standardimplementierung führt einen Aufruf von `glClear()` durch. Von Unterklassen wird nicht erwartet, dass sie die Implementierung der Basisklasse aufrufen; sie sollten das Löschen selbst durchführen.

Hinweis: Um die Portabilität zu gewährleisten, sollten Sie nicht davon ausgehen, dass der in ` initializeGL()` festgelegte Status erhalten bleibt. Legen Sie stattdessen alle erforderlichen Zustände fest, beispielsweise durch Aufruf von glEnable(), in paintGL(). Der Grund dafür ist, dass einige Plattformen, wie beispielsweise WebAssembly mit WebGL, unter bestimmten Umständen Einschränkungen hinsichtlich OpenGL-Kontexten aufweisen können, was dazu führen kann, dass der mit „ QOpenGLWidget “ verwendete Kontext auch für andere Zwecke genutzt wird.

Wenn „ QSurfaceFormat::StereoBuffers “ aktiviert ist, wird diese Funktion zweimal aufgerufen – einmal für jeden Puffer. Ermitteln Sie, welcher Puffer aktuell gebunden ist, indem Sie „ currentTargetBuffer()“ aufrufen.

Hinweis: Der Framebuffer jedes Ziels wird auch dann gezeichnet, wenn stereoskopisches Rendering von der Hardware nicht unterstützt wird. Im Fenster ist jedoch tatsächlich nur der linke Puffer sichtbar.

Siehe auch initializeGL(), resizeGL() und currentTargetBuffer().

[override virtual protected] QPaintDevice *QOpenGLWidget::redirected(QPoint *p) const

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

Implementiert: ` QWidget::resizeEvent` (`QResizeEvent *event`).

Behandelt Größenänderungsereignisse, die über den Ereignisparameter „ e “ übergeben werden. Ruft die virtuelle Funktion „ resizeGL()“ auf.

Hinweis: Vermeiden Sie es, diese Funktion in abgeleiteten Klassen zu überschreiben. Sollte dies nicht möglich sein, stellen Sie sicher, dass auch die Implementierung von ` QOpenGLWidget` aufgerufen wird. Andernfalls werden das zugrunde liegende Framebuffer-Objekt und die zugehörigen Ressourcen nicht korrekt in der Größe angepasst, was zu einer fehlerhaften Darstellung führt.

[virtual protected] void QOpenGLWidget::resizeGL(int w, int h)

Diese virtuelle Funktion wird immer dann aufgerufen, wenn die Größe des Widgets geändert wurde. Implementieren Sie sie in einer Unterklasse neu. Die neue Größe wird über die Parameter „ w “ und „ h “ übergeben.

Es ist nicht erforderlich, ` makeCurrent()` aufzurufen, da dies bereits beim Aufruf dieser Funktion geschehen ist. Zudem ist der Framebuffer bereits gebunden.

Siehe auch initializeGL() und paintGL().

[signal] void QOpenGLWidget::resized()

Dieses Signal wird unmittelbar nach der Neugenerierung des Framebuffer-Objekts aufgrund einer Größenänderung des Widgets ausgelöst.

void QOpenGLWidget::setFormat(const QSurfaceFormat &format)

Legt das gewünschte Oberflächen format fest.

Wenn das Format nicht explizit über diese Funktion festgelegt wird, wird das von ` QSurfaceFormat::defaultFormat()` zurückgegebene Format verwendet. Das bedeutet, dass bei mehreren OpenGL-Widgets einzelne Aufrufe dieser Funktion durch einen einzigen Aufruf von ` QSurfaceFormat::setDefaultFormat()` vor dem Erstellen des ersten Widgets ersetzt werden können.

Hinweis: Das Anfordern eines Alpha-Puffers über diese Funktion führt nicht zu den gewünschten Ergebnissen, wenn die Absicht besteht, darunterliegende Widgets sichtbar zu machen. Verwenden Sie stattdessen ` Qt::WA_AlwaysStackOnTop `, um halbtransparente ` QOpenGLWidget `-Instanzen zu aktivieren, bei denen darunterliegende Widgets sichtbar sind. Beachten Sie jedoch, dass dies die Stapelreihenfolge aufhebt, sodass es nicht mehr möglich ist, andere Widgets über dem ` QOpenGLWidget` zu platzieren.

Siehe auch „ format()“, „ Qt::WA_AlwaysStackOnTop “ und „ QSurfaceFormat::setDefaultFormat()“.

void QOpenGLWidget::setTextureFormat(GLenum texFormat)

Legt ein benutzerdefiniertes internes Texturformat fest: texFormat.

Bei der Arbeit mit sRGB-Framebuffern muss ein Format wie „ GL_SRGB8_ALPHA8 “ angegeben werden. Dies kann durch Aufruf dieser Funktion erreicht werden.

Hinweis: Diese Funktion hat keine Wirkung, wenn sie aufgerufen wird, nachdem das Widget bereits angezeigt wurde und somit die Initialisierung bereits durchgeführt wurde.

Hinweis: Diese Funktion muss in der Regel in Kombination mit einem Aufruf von ` QSurfaceFormat::setColorSpace()` verwendet werden, der den Farbraum auf ` QColorSpace::SRgb` setzt.

Siehe auch ` textureFormat()`.

void QOpenGLWidget::setUpdateBehavior(QOpenGLWidget::UpdateBehavior updateBehavior)

Legt das Aktualisierungsverhalten dieses Widgets auf „ updateBehavior “ fest.

Siehe auch „ updateBehavior()“.

GLenum QOpenGLWidget::textureFormat() const

Gibt das aktive interne Texturformat zurück, wenn das Widget bereits initialisiert wurde; das angeforderte Format, falls eines festgelegt wurde, das Widget jedoch noch nicht sichtbar gemacht wurde; oder ` nullptr `, wenn ` setTextureFormat()` nicht aufgerufen wurde und das Widget noch nicht sichtbar gemacht wurde.

Siehe auch ` setTextureFormat()`.

QOpenGLWidget::UpdateBehavior QOpenGLWidget::updateBehavior() const

Gibt das Aktualisierungsverhalten des Widgets zurück.

Siehe auch „ setUpdateBehavior()“.

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