QSGMaterial Class
Die Klasse „QSGMaterial“ kapselt den Rendering-Zustand eines Shader-Programms. Mehr...
| Header: | #include <QSGMaterial> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Quick) target_link_libraries(mytarget PRIVATE Qt6::Quick) |
| qmake: | QT += quick |
| Vererbt an: | QSGFlatColorMaterial, „ QSGOpaqueTextureMaterial “ sowie QSGVertexColorMaterial |
- Liste aller Mitglieder, einschließlich geerbter Mitglieder
- QSGMaterial ist Teil der Qt Quick -Szenengraph-Materialklassen.
Öffentliche Typen
| enum | Flag { Blending, RequiresDeterminant, RequiresFullMatrixExceptTranslate, RequiresFullMatrix, NoBatching, CustomCompileStep } |
| flags | Flags |
Öffentliche Funktionen
| virtual int | compare(const QSGMaterial *other) const |
| virtual QSGMaterialShader * | createShader(QSGRendererInterface::RenderMode renderMode) const = 0 |
| QSGMaterial::Flags | flags() const |
| void | setFlag(QSGMaterial::Flags flags, bool on = true) |
| virtual QSGMaterialType * | type() const = 0 |
(since 6.8) int | viewCount() const |
Ausführliche Beschreibung
„QSGMaterial“ und die Unterklassen von „ QSGMaterialShader “ stehen in enger Beziehung zueinander. Für einen Szenengraphen (einschließlich verschachtelter Graphen) gibt es eine eindeutige „ QSGMaterialShader “-Instanz, die die Shader kapseln, die der Szenengraph zum Rendern dieses Materials verwendet, beispielsweise einen Shader zur flächigen Einfärbung von Geometrie. Jeder „ QSGGeometryNode “ kann ein eindeutiges „QSGMaterial“ enthalten, das festlegt, wie der Shader beim Zeichnen dieses Knotens konfiguriert werden soll, beispielsweise die tatsächliche Farbe, die zum Rendern der Geometrie verwendet wird.
QSGMaterial verfügt über zwei virtuelle Funktionen, die beide implementiert werden müssen. Die Funktion ` type()` sollte für alle Instanzen einer bestimmten Unterklasse eine eindeutige Instanz zurückgeben. Die Funktion ` createShader()` sollte eine neue Instanz von ` QSGMaterialShader` zurückgeben, die spezifisch für diese Unterklasse von `QSGMaterial` ist.
Eine minimale Implementierung von „QSGMaterial“ könnte wie folgt aussehen:
class Material : public QSGMaterial
{
public:
QSGMaterialType *type() const override { static QSGMaterialType type; return &type; }
QSGMaterialShader *createShader(QSGRendererInterface::RenderMode) const override { return new Shader; }
};Im Beispiel „Custom Material“ finden Sie eine Einführung in die Implementierung einer QQuickItem -Unterklasse, die auf einer QSGGeometryNode und einem benutzerdefinierten Material basiert.
Hinweis: ` createShader()` wird pro ` QSGMaterialType` nur einmal aufgerufen, um redundanten Aufwand bei der Shader-Vorbereitung zu vermeiden. Wenn ein `QSGMaterial` auf mehreren Kombinationen aus Vertex- und Fragment-Shadern basiert, muss die Implementierung von ` type()` für jede Shader-Kombination einen anderen, eindeutigen ` QSGMaterialType `-Zeiger zurückgeben.
Hinweis: Alle Klassen mit dem Präfix „QSG“ sollten ausschließlich im Rendering-Thread des Szenengraphen verwendet werden. Weitere Informationen finden Sie unter „Szenengraph“ und „Rendering “.
Siehe auch „ QSGMaterialShader“ , „Scene Graph – Custom Material“, „Scene Graph – Two Texture Providers“ und „Scene Graph – Graph“.
Dokumentation zu Mitgliedstypen
enum QSGMaterial::Flag
flags QSGMaterial::Flags
| Konstante | Wert | Beschreibung |
|---|---|---|
QSGMaterial::Blending | 0x0001 | Setzen Sie dieses Flag auf „true“, wenn für das Material beim Rendern das Blending aktiviert sein muss. |
QSGMaterial::RequiresDeterminant | 0x0002 | Setzen Sie dieses Flag auf „true“, wenn das Material beim Rendern auf den Determinantenwert der Matrix der Geometrieknoten angewiesen ist. |
QSGMaterial::RequiresFullMatrixExceptTranslate | 0x0004 | RequiresDeterminant | Setzen Sie dieses Flag auf „true“, wenn das Material beim Rendern auf die vollständige Matrix der Geometrieknoten zurückgreift, mit Ausnahme des Translationsanteils. |
QSGMaterial::RequiresFullMatrix | 0x0008 | RequiresFullMatrixExceptTranslate | Setzen Sie dieses Flag auf „true“, wenn das Material beim Rendern auf die vollständige Matrix der Geometrieknoten zurückgreift. |
QSGMaterial::NoBatching | 0x0010 | Setzen Sie dieses Flag auf „true“, wenn das Material Shader verwendet, die mit dem Batching-Mechanismus des Szenengraphen inkompatibel sind. Dies ist bei bestimmten fortgeschrittenen Anwendungen relevant, beispielsweise bei der direkten Manipulation von „ gl_Position.z “ im Vertex-Shader. Solche Lösungen sind oft an eine bestimmte Szenenstruktur gebunden und lassen sich wahrscheinlich nicht sicher mit beliebigen Inhalten in einer Szene verwenden. Daher sollte dieses Flag nur nach entsprechender Prüfung gesetzt werden und wird für die überwiegende Mehrheit der Materialien niemals benötigt. Das Setzen dieses Flags kann aufgrund der Notwendigkeit, mehr Draw-Calls auszuführen, zu einer verminderten Leistung führen. Dieses Flag wurde in Qt 6.3 eingeführt. |
QSGMaterial::CustomCompileStep | NoBatching | In Qt 6 ist dieses Flag identisch mit „NoBatching“. Verwenden Sie stattdessen lieber „NoBatching“. |
Der Typ „Flags“ ist ein „typedef“ für „QFlags<Flag>“. Er speichert eine OR-Kombination von „Flag“-Werten.
Dokumentation der Mitgliedsfunktionen
[virtual] int QSGMaterial::compare(const QSGMaterial *other) const
Vergleicht dieses Material mit other und gibt 0 zurück, wenn sie gleich sind; -1, wenn dieses Material vor other sortiert werden soll, und 1, wenn other vor diesem sortiert werden soll.
Der Szenengraph kann Geometrieknoten neu anordnen, um Zustandsänderungen zu minimieren. Die Vergleichsfunktion wird während des Sortiervorgangs aufgerufen, damit die Materialien so sortiert werden können, dass die Zustandsänderungen bei jedem Aufruf von `QSGMaterialShader::updateState()` minimiert werden.
Es wird garantiert, dass der Zeiger „this“ und „ other “ denselben Wert von type() haben.
[pure virtual] QSGMaterialShader *QSGMaterial::createShader(QSGRendererInterface::RenderMode renderMode) const
Diese Funktion gibt eine neue Instanz der Implementierung von ` QSGMaterialShader ` zurück, die zum Rendern von Geometrie für eine bestimmte Implementierung von ` QSGMaterial` verwendet wird.
Die Funktion wird für jede Kombination aus Materialtyp und „ renderMode “ nur einmal aufgerufen und intern zwischengespeichert.
Bei den meisten Materialien kann ` renderMode ` ignoriert werden. Einige wenige Materialien erfordern möglicherweise eine benutzerdefinierte Behandlung für bestimmte Rendermodi. Dies ist beispielsweise der Fall, wenn das Material Antialiasing so implementiert, dass bei Verwendung von `RenderMode3D` perspektivische Transformationen berücksichtigt werden müssen.
QSGMaterial::Flags QSGMaterial::flags() const
Gibt die Flags des Materials zurück.
void QSGMaterial::setFlag(QSGMaterial::Flags flags, bool on = true)
Setzt die Flags „ flags “ für dieses Material, wenn „ on “ wahr ist; andernfalls wird das Attribut zurückgesetzt.
[pure virtual] QSGMaterialType *QSGMaterial::type() const
Diese Funktion wird vom Szenengraphen aufgerufen, um eine Kennung abzufragen, die für die von ` createShader()` instanziierte ` QSGMaterialShader `-Instanz eindeutig ist.
Bei vielen Materialien besteht der übliche Ansatz darin, einen Zeiger auf eine statische und somit global verfügbare „ QSGMaterialType “-Instanz zurückzugeben. Das „ QSGMaterialType “ ist ein undurchsichtiges Objekt. Sein Zweck besteht lediglich darin, als typsichere, einfache Möglichkeit zur Generierung eindeutiger Materialkennungen zu dienen.
QSGMaterialType *type() const override
{
static QSGMaterialType type;
return &type;
}[since 6.8] int QSGMaterial::viewCount() const
Gibt die Anzahl der Ansichten zurück, falls das Material bei der Multiview-Darstellung verwendet wird.
Hinweis: Der Rückgabewert ist nur gültig, wenn die Funktion von ` createShader()` aufgerufen wird und danach. Der Wert ist nicht unbedingt aktuell, bevor ` createShader()` vom Szenengraphen aufgerufen wird.
Normalerweise lautet der Rückgabewert „ 1 “. Eine Ansichtsanzahl größer als 2 deutet auf einen Multiview-Renderdurchlauf hin. Von Materialien, die Multiview unterstützen, wird erwartet, dass sie `viewCount()` in ` createShader()` oder in ihrem Konstruktor ` QSGMaterialShader ` abfragen und sicherstellen, dass die entsprechenden Shader ausgewählt werden. Vom Vertex-Shader wird dann erwartet, dass er ` gl_ViewIndex ` verwendet, um das Array der Model-View-Projektionsmatrizen zu indizieren, da im Multiview-Modus mehrere Matrizen vorhanden sind (eine für jede Ansicht).
Nehmen wir als Beispiel den folgenden einfachen Vertex-Shader:
#version 440
layout(location = 0) in vec4 vertexCoord;
layout(location = 1) in vec4 vertexColor;
layout(location = 0) out vec4 color;
layout(std140, binding = 0) uniform buf {
mat4 matrix[2];
float opacity;
};
void main()
{
gl_Position = matrix[gl_ViewIndex] * vertexCoord;
color = vertexColor * opacity;
}Dieser Shader ist für die Verarbeitung von genau zwei Ansichten ausgelegt. Er ist nicht mit einer anderen Anzahl von Ansichten kompatibel. Bei der Konditionierung des Shaders muss das Tool „ qsb “ mit dem Befehl „ --view-count 2 “ aufgerufen werden oder, bei Verwendung der CMake-Integration, muss im Befehl „ qt_add_shaders() “ „ VIEW_COUNT 2 “ angegeben werden.
Hinweis: Eine Zeile mit #extension GL_EXT_multiview : require wird automatisch von qsb eingefügt, sobald eine Ansichtsanzahl von 2 oder mehr festgelegt wird.
Entwicklern wird empfohlen, die automatisch eingefügte Präprozessorvariable QSHADER_VIEW_COUNT zu verwenden, um den Umgang mit unterschiedlichen Ansichtsanzahlen zu vereinfachen. Wenn beispielsweise in derselben Quelldatei sowohl Nicht-Multiview- als auch Multiview-Ansichten mit einer Ansichtsanzahl von 2 unterstützt werden sollen, könnte Folgendes getan werden:
#version 440
layout(location = 0) in vec4 vertexCoord;
layout(location = 1) in vec4 vertexColor;
layout(location = 0) out vec4 color;
layout(std140, binding = 0) uniform buf {
#if QSHADER_VIEW_COUNT >= 2
mat4 matrix[QSHADER_VIEW_COUNT];
#else
mat4 matrix;
#endif
float opacity;
};
void main()
{
#if QSHADER_VIEW_COUNT >= 2
gl_Position = matrix[gl_ViewIndex] * vertexCoord;
#else
gl_Position = matrix * vertexCoord;
#endif
color = vertexColor * opacity;
}Die gleiche Quelldatei kann nun zweimal über „ qsb “ oder „ qt_add_shaders() “ ausgeführt werden – einmal ohne Angabe der Ansichtsanzahl und einmal mit einer auf 2 festgelegten Ansichtsanzahl. Das Material kann dann zur Laufzeit anhand von `viewCount()` die passende `.qsb`-Datei auswählen.
Mit CMake könnte dies in etwa wie folgt aussehen. In diesem Beispiel wird erwartet, dass die entsprechende Datei „ QSGMaterialShader “ basierend auf dem Wert von `viewCount()` zwischen „ :/shaders/example.vert.qsb “ und „ :/shaders/multiview/example.vert.qsb “ wählt. (Das Gleiche gilt für den Fragment-Shader.)
qt_add_shaders(application "application_shaders"
PREFIX
/
FILES
shaders/example.vert
shaders/example.frag
)
qt_add_shaders(application "application_multiview_shaders"
GLSL
330,300es
HLSL
61
MSL
12
VIEW_COUNT
2
PREFIX
/
FILES
shaders/example.vert
shaders/example.frag
OUTPUTS
shaders/multiview/example.vert
shaders/multiview/example.frag
)Hinweis: Der Fragment-Shader sollte genauso behandelt werden wie der Vertex-Shader, auch wenn der Fragment-Shader-Code keine Abhängigkeit von der Ansichtsanzahl (gl_ViewIndex) haben darf, um maximale Portabilität zu gewährleisten. Es gibt zwei Gründe, auch Fragment-Shader in den Multiview-Satz aufzunehmen. Zum einen kann das Mischen verschiedener Shader-Versionen innerhalb derselben Grafik-Pipeline je nach der zugrunde liegenden Grafik-API problematisch sein: Bei D3D12 würde beispielsweise das Mischen von HLSL-Shadern für die Shader-Modelle 5.0 und 6.1 einen Fehler verursachen. Der andere Grund ist, dass die Definition von „ QSHADER_VIEW_COUNT “ in Fragment-Shadern sehr nützlich sein kann, beispielsweise wenn ein Uniform-Buffer-Layout zwischen der Vertex- und der Fragment-Stufe gemeinsam genutzt wird.
Hinweis: Für OpenGL ist die Mindestversion von GLSL für Vertex-Shader, die auf „ gl_ViewIndex “ zurückgreifen, „ 330 “. Niedrigere Versionen werden möglicherweise zur Kompilierungszeit akzeptiert, können jedoch je nach OpenGL-Implementierung zu einem Fehler zur Laufzeit führen.
Der Einfachheit halber gibt es auch eine Option „ MULTIVIEW “ für `qt_add_shaders()`. Diese führt zunächst das Tool ` qsb ` normal aus, überschreibt dann ` VIEW_COUNT ` durch ` 2`, setzt ` GLSL`, ` HLSL` und ` MSL ` auf geeignete Standardwerte und führt ` qsb ` erneut aus, wobei diesmal `.qsb`-Dateien mit einem angehängten Suffix ausgegeben werden. Die Materialimplementierung kann dann die Überladung von ` QSGMaterialShader::setShaderFileName()` verwenden, die ein Argument vom Typ ` viewCount ` entgegennimmt, das automatisch die richtige `.qsb`-Datei auswählt.
Das Folgende entspricht daher weitgehend dem oben gezeigten Beispielaufruf, mit dem Unterschied, dass keine manuell verwalteten Ausgabedateien angegeben werden müssen. Beachten Sie, dass es Fälle geben kann, in denen die automatisch ausgewählten Shading-Sprachversionen nicht ausreichen; in diesem Fall sollten Anwendungen weiterhin alles explizit angeben.
qt_add_shaders(application "application_multiview_shaders"
MULTIVIEW
PREFIX
/
FILES
shaders/example.vert
shaders/example.frag
)Weitere Details auf niedrigerer Ebene zur Multiview-Unterstützung in Qt finden Sie unter QRhi::MultiView, QRhiColorAttachment::setMultiViewCount() und QRhiGraphicsPipeline::setMultiViewCount(). Der „ Qt Quick “-Szenengraph-Renderer ist darauf vorbereitet, Multiview-Renderziele zu erkennen, wenn diese über QQuickRenderTarget::fromRhiRenderTarget() oder die 3D-API-spezifischen Funktionen wie fromVulkanImage() mit einem Argument „ arraySize “ größer als 1 angegeben werden. Der Renderer leitet die Anzahl der Ansichten dann an die Grafik-Pipelines und die Materialien weiter.
Diese Funktion wurde in Qt 6.8 eingeführt.
© 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.