QSGMaterialShader Class

Die Klasse QSGMaterialShader repräsentiert ein Grafik-API-unabhängiges Shader-Programm. Mehr...

Kopfzeile: #include <QSGMaterialShader>
CMake: find_package(Qt6 REQUIRED COMPONENTS Quick)
target_link_libraries(mytarget PRIVATE Qt6::Quick)
qmake: QT += quick

Öffentliche Typen

struct GraphicsPipelineState
class RenderState
enum Flag { UpdatesGraphicsPipelineState }
flags Flags

Öffentliche Funktionen

QSGMaterialShader()
(since 6.4) int combinedImageSamplerCount(int binding) const
QSGMaterialShader::Flags flags() const
void setFlag(QSGMaterialShader::Flags flags, bool on = true)
void setFlags(QSGMaterialShader::Flags flags)
virtual bool updateGraphicsPipelineState(QSGMaterialShader::RenderState &state, QSGMaterialShader::GraphicsPipelineState *ps, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
virtual void updateSampledImage(QSGMaterialShader::RenderState &state, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
virtual bool updateUniformData(QSGMaterialShader::RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)

Geschützte Funktionen

void setShader(QSGMaterialShader::Stage stage, const QShader &shader)
void setShaderFileName(QSGMaterialShader::Stage stage, const QString &filename)
(since 6.8) void setShaderFileName(QSGMaterialShader::Stage stage, const QString &filename, int viewCount)

Detaillierte Beschreibung

QSGMaterialShader repräsentiert eine Kombination aus Vertex- und Fragment-Shadern, Daten, die die Zustandsänderungen der Grafikpipeline definieren, und Logik, die Grafikressourcen, wie einheitliche Puffer und Texturen, aktualisiert.

Hinweis: Alle Klassen mit QSG-Präfix sollten ausschließlich im Rendering-Thread des Szenegraphs verwendet werden. Siehe Szenengraph und Rendering für weitere Informationen.

Die QSGMaterial und QSGMaterialShader bilden eine enge Beziehung. Für einen Szenengraphen (einschließlich verschachtelter Graphen) gibt es eine eindeutige QSGMaterialShader-Instanz, die die Shader und andere Daten kapselt, die der Szenengraph zum Rendern eines Objekts mit diesem Material verwendet. Jedes QSGGeometryNode kann eine eindeutige QSGMaterial haben, die definiert, wie die Grafikpipeline beim Zeichnen des Knotens konfiguriert werden muss. Eine Instanz von QSGMaterialShader wird nie explizit vom Benutzer erstellt, sie wird bei Bedarf vom Szenegraph durch QSGMaterial::createShader() erstellt. Der Szenegraph erzeugt eine Instanz von QSGMaterialShader durch den Aufruf der Methode QSGMaterial::createShader(), wodurch sichergestellt wird, dass es nur eine Instanz jeder Shader-Implementierung gibt.

In Qt 5 war QSGMaterialShader an OpenGL gebunden. Es wurde direkt auf QOpenGLShaderProgram aufgebaut und hatte Funktionen wie updateState(), die beliebige OpenGL-Befehle ausgeben konnten. Dies ist in Qt 6 nicht mehr der Fall. QSGMaterialShader ist nicht streng datenorientiert, was bedeutet, dass es Daten (Shader und die gewünschten Pipeline-Zustandsänderungen) zusammen mit einer Logik bereitstellt, die Daten in einem einheitlichen Puffer aktualisiert. Der Zugriff auf die Grafik-API ist nicht vorgesehen. Das bedeutet, dass ein QSGMaterialShader keine eigenen OpenGL-, Vulkan-, Metal- oder Direct 3D-Aufrufe tätigen kann. Zusammen mit der einheitlichen Shader-Verwaltung ermöglicht dies, dass ein QSGMaterialShader einmal geschrieben werden kann und zur Laufzeit mit jeder der unterstützten Grafik-APIs funktioniert.

Die Shader, die durch den Aufruf der geschützten Funktion setShaderFileName() gesetzt werden, steuern, was das Material mit den Vertexdaten der Geometrie macht und wie die Fragmente schattiert werden. Ein QSGMaterialShader wird typischerweise einen Vertex- und einen Fragment-Shader während der Konstruktion setzen. Ein nachträgliches Ändern der Shader führt möglicherweise nicht zu dem gewünschten Effekt und muss vermieden werden.

In Qt 6 werden standardmäßig .qsb Dateien mit der Anwendung ausgeliefert, die typischerweise über das Ressourcensystem eingebettet sind und beim Aufruf von setShaderFileName() referenziert werden. Die .qsb Dateien werden offline oder spätestens bei der Erstellung der Anwendung aus GLSL-Quellcode im Vulkan-Stil mit dem qsb Tool aus dem Qt Shader Tools Modul generiert.

Es gibt drei Virtuals, die überschrieben werden können. Diese stellen die Daten oder die Logik zur Erzeugung der Daten für einheitliche Puffer, Texturen und Pipeline-Zustandsänderungen bereit.

updateUniformData() ist die Funktion, die am häufigsten in Unterklassen reimplementiert wird. Von dieser Funktion wird erwartet, dass sie den Inhalt von QByteArray aktualisiert, der dann den Shadern als einheitlicher Puffer zur Verfügung gestellt wird. Jeder QSGMaterialShader, der einen einheitlichen Block in seinem Vertex- oder Fragment-Shader hat, muss updateUniformData() neu implementieren.

updateSampledImage() ist relevant, wenn der Shader-Code Texturen sampelt. Die Funktion wird für jeden Sampler (oder kombinierten Bildsampler, in APIs, wo dies relevant ist) aufgerufen und gibt ihm die Möglichkeit, anzugeben, welche QSGTexture dem Shader ausgesetzt werden soll.

Die Zustandsänderungen in der Shader-Pipeline werden weniger häufig verwendet. Ein Anwendungsfall sind Materialien, die einen bestimmten Mischmodus verwenden möchten. Die entsprechende Funktion ist updateGraphicsPipelineState(). Diese Funktion wird nur dann aufgerufen, wenn der QSGMaterialShader durch Setzen des Flags UpdatesGraphicsPipelineState zugestimmt hat. Die Aufgabe der Funktion ist es, die ihr übergebene GraphicsPipelineState struct-Instanz mit den gewünschten Änderungen zu aktualisieren. Derzeit sind nur Blending- und Culling-bezogene Funktionen verfügbar, andere Zustände können nicht durch Materialien gesteuert werden.

Ein minimales Beispiel, das auch Texturunterstützung beinhaltet, könnte das folgende sein. Hier nehmen wir an, dass Material die QSGMaterial ist, die eine Instanz von Shader in ihrer createShader() erstellt, und dass sie eine QSGTexture enthält, die wir im Fragment-Shader abtasten wollen. Der Vertex-Shader stützt sich nur auf die Modelview-Projektionsmatrix.

class Shader : public QSGMaterialShader
{
public:
    Shader()
    {
        setShaderFileName(VertexStage, QLatin1String(":/materialshader.vert.qsb"));
        setShaderFileName(FragmentStage, QLatin1String(":/materialshader.frag.qsb"));
    }

    bool updateUniformData(RenderState &state, QSGMaterial *, QSGMaterial *)
    {
        bool changed = false;
        QByteArray *buf = state.uniformData();
        if (state.isMatrixDirty()) {
            const QMatrix4x4 m = state.combinedMatrix();
            memcpy(buf->data(), m.constData(), 64);
            changed = true;
        }
        return changed;
    }

    void updateSampledImage(RenderState &, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *)
    {
        Material *mat = static_cast<Material *>(newMaterial);
        if (binding == 1)
            *texture = mat->texture();
    }
};

Der GLSL-Quellcode für die Shader im Vulkan-Stil könnte wie folgt aussehen. Es wird erwartet, dass diese offline mit dem qsb Tool vorverarbeitet werden, das die .qsb Dateien erzeugt, auf die im Shader() Konstruktor verwiesen wird.

#version 440
layout(location = 0) in vec4 aVertex;
layout(location = 1) in vec2 aTexCoord;
layout(location = 0) out vec2 vTexCoord;
layout(std140, binding = 0) uniform buf {
    mat4 qt_Matrix;
} ubuf;
out gl_PerVertex { vec4 gl_Position; };
void main() {
    gl_Position = ubuf.qt_Matrix * aVertex;
    vTexCoord = aTexCoord;
}
#version 440
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 fragColor;
layout(binding = 1) uniform sampler2D srcTex;
void main() {
    vec4 c = texture(srcTex, vTexCoord);
    fragColor = vec4(c.rgb * 0.5, 1.0);
}

Hinweis: Alle Klassen mit dem Präfix QSG sollten ausschließlich im Rendering-Thread des Szenegraphs verwendet werden. Siehe Scene Graph und Rendering für weitere Informationen.

Siehe auch QSGMaterial, Scene Graph - Custom Material, Scene Graph - Two Texture Providers und Scene Graph - Graph.

Dokumentation der Mitgliedstypen

enum QSGMaterialShader::Flag
flags QSGMaterialShader::Flags

Flag-Werte zur Angabe spezieller Materialeigenschaften.

KonstanteWertBeschreibung
QSGMaterialShader::UpdatesGraphicsPipelineState0x0001Das Setzen dieses Flags ermöglicht den Aufruf von updateGraphicsPipelineState().

Der Typ Flags ist ein Typedef für QFlags<Flag>. Er speichert eine ODER-Kombination von Flag-Werten.

Dokumentation der Mitgliedsfunktionen

QSGMaterialShader::QSGMaterialShader()

Konstruiert einen neuen QSGMaterialShader.

[since 6.4] int QSGMaterialShader::combinedImageSamplerCount(int binding) const

Gibt die Anzahl der Elemente in der kombinierten Bild-Sampler-Variable auf binding zurück. Dieser Wert wird aus dem Shader-Code introspektiert. Bei der Variablen kann es sich um ein Array handeln, das mehr als eine Dimension haben kann.

Die Anzahl spiegelt die Gesamtzahl der kombinierten Bildsammler-Elemente in der Variablen wider. Im folgenden Beispiel ist die Anzahl für srcA gleich 1, für srcB gleich 4 und für srcC gleich 6.

layout (binding = 0) uniform sampler2D srcA;
layout (binding = 1) uniform sampler2D srcB[4];
layout (binding = 2) uniform sampler2D srcC[2][3];

Diese Anzahl ist die Anzahl der QSGTexture Zeiger im Texturparameter von QSGMaterialShader::updateSampledImage.

Diese Funktion wurde in Qt 6.4 eingeführt.

Siehe auch QSGMaterialShader::updateSampledImage.

QSGMaterialShader::Flags QSGMaterialShader::flags() const

Gibt die aktuell gesetzten Flags für diesen Material-Shader zurück.

Siehe auch setFlags().

void QSGMaterialShader::setFlag(QSGMaterialShader::Flags flags, bool on = true)

Setzt die flags auf diesen Material-Shader, wenn on wahr ist; andernfalls werden die angegebenen Flags gelöscht.

void QSGMaterialShader::setFlags(QSGMaterialShader::Flags flags)

Setzt die flags für diesen Material-Shader.

Siehe auch flags().

[protected] void QSGMaterialShader::setShader(QSGMaterialShader::Stage stage, const QShader &shader)

Legt die shader für die angegebene stage fest.

[protected] void QSGMaterialShader::setShaderFileName(QSGMaterialShader::Stage stage, const QString &filename)

Legt die filename für den Shader für die angegebene stage fest.

Es wird erwartet, dass die Datei eine serialisierte QShader enthält.

[protected, since 6.8] void QSGMaterialShader::setShaderFileName(QSGMaterialShader::Stage stage, const QString &filename, int viewCount)

Legt die filename für den Shader für die angegebene stage fest.

Es wird erwartet, dass die Datei eine serialisierte QShader enthält.

Diese Überladung wird verwendet, wenn das multiview Rendering aktiviert wird, insbesondere wenn die MULTIVIEW-Komfortoption des Buildsystems verwendet wird.

viewCount sollte 2, 3 oder 4 sein. Die filename wird automatisch auf dieser Basis angepasst.

Diese Funktion wurde in Qt 6.8 eingeführt.

[virtual] bool QSGMaterialShader::updateGraphicsPipelineState(QSGMaterialShader::RenderState &state, QSGMaterialShader::GraphicsPipelineState *ps, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)

Diese Funktion wird vom Szenengraphen aufgerufen, damit das Material einen benutzerdefinierten Satz von Grafikzuständen bereitstellen kann. Der Satz von Zuständen, die durch das Material angepasst werden können, ist auf Überblendungen und verwandte Einstellungen beschränkt.

Hinweis: Diese Funktion wird nur aufgerufen, wenn das Kennzeichen UpdatesGraphicsPipelineState über setFlags() aktiviert wurde. Standardmäßig ist es nicht gesetzt, und daher wird diese Funktion nie aufgerufen.

Der Rückgabewert muss true sein, wenn eine Änderung an einem der Elemente in ps vorgenommen wurde.

Hinweis: Der Inhalt von ps bleibt zwischen Aufrufen dieser Funktion nicht erhalten.

Das aktuelle Rendering state wird aus dem Szenengraph übergeben.

Der subklassenspezifische Status kann aus newMaterial extrahiert werden. Wenn oldMaterial null ist, wurde dieser Shader gerade aktiviert.

[virtual] void QSGMaterialShader::updateSampledImage(QSGMaterialShader::RenderState &state, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)

Diese Funktion wird vom Szenengraph aufgerufen, um die Verwendung von gesampelten Bildern im Shader vorzubereiten, typischerweise in Form von kombinierten Bild-Samplern.

binding ist die Bindungsnummer des Samplers. Die Funktion wird für jede kombinierte Bild-Sampler-Variable im Shader-Code aufgerufen, der mit QSGMaterialShader verbunden ist.

texture ist ein Array von QSGTexture -Zeigern. Die Anzahl der Elemente im Array entspricht der Anzahl der Elemente in der im Shader-Code angegebenen Bild-Sampler-Variablen. Diese Variable kann ein Array sein und kann mehr als eine Dimension haben. Die Anzahl der Elemente in dem Array kann über QSGMaterialShader::combinedImageSamplerCount

Wenn ein Element in texture null ist, muss es vor der Rückkehr auf einen gültigen QSGTexture -Zeiger gesetzt werden. Wenn es nicht null ist, muss das Material entscheiden, ob ein neues QSGTexture * gespeichert wird oder ob es einige Parameter des bereits bekannten QSGTexture aktualisiert. Das Eigentum an QSGTexture wird nicht übertragen.

Das aktuelle Rendering state wird vom Szenengraphen übergeben. Gegebenenfalls obliegt es dem Material, das Hochladen von Texturdaten über QSGTexture::commitTextureOperations() anzustoßen.

Der subklassenspezifische Zustand kann aus newMaterial extrahiert werden.

oldMaterial kann verwendet werden, um Änderungen zu minimieren. Wenn oldMaterial null ist, wurde dieser Shader gerade aktiviert.

Siehe auch QSGMaterialShader::combinedImageSamplerCount.

[virtual] bool QSGMaterialShader::updateUniformData(QSGMaterialShader::RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)

Diese Funktion wird vom Szenengraph aufgerufen, um den Inhalt des einheitlichen Puffers des Shader-Programms zu aktualisieren. Von der Implementierung wird nicht erwartet, dass sie echte Grafikoperationen durchführt, sie ist lediglich für das Kopieren von Daten in den von RenderState::uniformData() zurückgegebenen QByteArray verantwortlich. Der Szenengraph sorgt dafür, dass dieser Puffer in den Shadern sichtbar wird.

Das aktuelle Rendering state wird vom Szenengraphen übergeben. Wenn der Zustand anzeigt, dass ein relevanter Zustand verschmutzt ist, muss die Implementierung den entsprechenden Bereich in den Pufferdaten aktualisieren, der über RenderState::uniformData() zugänglich ist. Wenn ein Zustand, z. B. Matrix oder Deckkraft, nicht verschmutzt ist, muss der entsprechende Bereich nicht berührt werden, da die Daten beständig sind.

Der Rückgabewert muss true lauten, wenn eine Änderung an den einheitlichen Daten vorgenommen wurde.

Der subklassenspezifische Zustand, wie z.B. die Farbe eines flachen Farbmaterials, sollte aus newMaterial extrahiert werden, um die entsprechenden Regionen im Puffer entsprechend zu aktualisieren.

oldMaterial kann verwendet werden, um Pufferänderungen (bei denen es sich in der Regel um Memcpy-Aufrufe handelt) bei der Aktualisierung von Materialzuständen zu minimieren. Wenn oldMaterial null ist, wurde dieser Shader gerade aktiviert.

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