Класс QSGMaterialShader
Класс QSGMaterialShader представляет собой программу шейдеров, независимую от графического API. Подробнее...
| Заголовок: | #include <QSGMaterialShader> |
| CMake: | find_package(Qt6 COMPONENTS Quick REQUIRED) target_link_libraries(mytarget PRIVATE Qt6::Quick) |
| qmake: | QT += quick |
| С тех пор: | Qt 5.14 |
Открытые типы
| структура | GraphicsPipelineState |
| класс | RenderState |
| перечисление | Flag { UpdatesGraphicsPipelineState } |
| флаги | Flags |
Открытые функции
| QSGMaterialShader() | |
| QSGMaterialShader::Flags | flags() const |
| void | setFlag(QSGMaterialShader::Flags flags, bool on = true) |
| void | setFlags(QSGMaterialShader::Flags flags) |
| виртуальный bool | updateGraphicsPipelineState(QSGMaterialShader::RenderState &state, QSGMaterialShader::GraphicsPipelineState *ps, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) |
| виртуальный void | updateSampledImage(QSGMaterialShader::RenderState &state, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) |
| виртуальный bool | updateUniformData(QSGMaterialShader::RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) |
Защищенные функции
| void | setShader(QSGMaterialShader::Stage stage, const QShader &shader) |
| void | setShaderFileName(QSGMaterialShader::Stage stage, const QString &filename) |
Подробное описание
QSGMaterialShader представляет собой сочетание вершинного и фрагментного шейдеров, данных, определяющих изменения состояния графического конвейера, и логики, которая обновляет графические ресурсы, такие как унифицированные буферы и текстуры.
Примечание: Все классы с префиксом QSG должны использоваться только в потоке отрисовки графа сцены. Дополнительную информацию см. в разделе Граф сцены и отрисовка.
QSGMaterial и QSGMaterialShader образуют тесную связь. Для одной сцены графа (включая вложенные графики) существует один уникальный экземпляр QSGMaterialShader, который инкапсулирует шейдеры и другие данные, используемые графиком сцены для отрисовки объекта с этим материалом. Каждый QSGGeometryNode может иметь уникальный QSGMaterial, который определяет, как должен быть настроен графический конвейер при отрисовке узла. Экземпляр QSGMaterialShader никогда не создается пользователем явно, он будет создан по запросу графом сцены с помощью QSGMaterial::createShader(). Граф сцены создает экземпляр QSGMaterialShader, вызывая метод QSGMaterial::createShader(), гарантируя, что существует только один экземпляр каждой реализации шейдера.
В Qt 5 QSGMaterialShader был привязан к OpenGL. Он был построен непосредственно на QOpenGLShaderProgram и имел функции, такие как updateState(), которые могли выдавать произвольные команды OpenGL. Это больше не так в Qt 6. QSGMaterialShader не является строго ориентированным на данные, то есть он предоставляет данные (шейдеры и желаемые изменения состояния конвейера) вместе с логикой, которая обновляет данные в унифицированном буфере. Доступ к графическому API не предоставляется. Это означает, что QSGMaterialShader не может самостоятельно выполнять вызовы OpenGL, Vulkan, Metal или Direct 3D. Вместе с унифицированным управлением шейдерами это позволяет написать QSGMaterialShader один раз и сделать его функциональным с любым из поддерживаемых графических API во время выполнения.
Шейдеры, заданные с помощью защищенной функции setShaderFileName(), контролируют то, как материал работает с вершинными данными из геометрии и как затемняются фрагменты. QSGMaterialShader обычно устанавливает вершинный и фрагментный шейдеры во время создания. Изменение шейдеров после этого может не привести к желаемому эффекту и должно быть избегаемо.
В Qt 6, подход по умолчанию заключается в поставке .qsb файлов с приложением, обычно встроенных через систему ресурсов, и ссылаются при вызове setShaderFileName(). Файлы .qsb генерируются автономно или, в крайнем случае, во время компиляции приложения из исходного кода GLSL в стиле Vulkan с помощью инструмента qsb из модуля Qt Shader Tools.
Есть три виртуальные функции, которые можно переопределить. Они предоставляют данные или логику для генерации данных для унифицированных буферов, текстур и изменений состояния конвейера.
updateUniformData() — функция, которая чаще всего переопределяется в подклассах. Эта функция должна обновлять содержимое QByteArray, которое затем будет представлено шейдерам в качестве унифицированного буфера. Любой QSGMaterialShader, имеющий блок унифицированных переменных в своём вершинном или фрагментном шейдере, должен переопределить updateUniformData().
updateSampledImage() относится к случаям, когда код шейдера сэмплирует текстуры. Функция будет вызываться для каждого сэмплера (или комбинированного сэмплера изображения в API, где это уместно), предоставляя возможность указать, какой QSGTexture должен быть доступен шейдеру.
Изменения состояния конвейера шейдера используются реже. Один из случаев использования — материалы, которые хотят использовать определённый режим смешивания. Соответствующая функция — updateGraphicsPipelineState(). Эта функция не вызывается, если QSGMaterialShader не выбрал её, установив флаг UpdatesGraphicsPipelineState. Задача функции — обновить экземпляр структуры GraphicsPipelineState, переданный ей, с желаемыми изменениями. В настоящее время доступны только функции смешивания и обрезки; другие состояния нельзя контролировать с помощью материалов.
Приведён минимальный пример, который также включает поддержку текстур. Здесь мы предполагаем, что Material — это QSGMaterial, который создаёт экземпляр Shader в своём createShader(), и что он содержит QSGTexture, который мы хотим сэмплировать в фрагментном шейдере. Вершинный шейдер полагается только на матрицу модели-представления-проекции.
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();
}
}; Исходный код шейдеров в стиле Vulkan GLSL может выглядеть следующим образом. Ожидается, что они будут предварительно обработаны автономно с помощью инструмента qsb, который генерирует файлы .qsb, на которые ссылается конструктор Shader().
#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);
} Примечание: Все классы с префиксом QSG должны использоваться только в потоке отрисовки графа сцены. Дополнительную информацию см. в разделе Граф сцены и отрисовка.
См. также QSGMaterial, Граф сцены - Настройка материала, Граф сцены - Два поставщика текстур и Граф сцены - График.
Документация по типам членов
перечисление QSGMaterialShader::Flagфлаги QSGMaterialShader::Flags
Значения флагов для указания специальных свойств материала.
| Константа | Значение | Описание |
|---|---|---|
QSGMaterialShader::UpdatesGraphicsPipelineState |
0x0001 |
Установка этого флага позволяет вызывать updateGraphicsPipelineState(). |
Тип Flags является псевдонимом для QFlags<Flag>. Он хранит логическое ИЛИ сочетание значений Flag.
Документация по функциям-членам
QSGMaterialShader::QSGMaterialShader()
Создаёт новый QSGMaterialShader.
QSGMaterialShader::Flags QSGMaterialShader::flags() const
Возвращает текущие установленные флаги для данного шейдера материала.
См. также setFlags().
void QSGMaterialShader::setFlag(QSGMaterialShader::Flags flags, bool on = true)
Устанавливает flags для данного шейдера материала, если on равно true; в противном случае очищает указанные флаги.
void QSGMaterialShader::setFlags(QSGMaterialShader::Flags flags)
Устанавливает flags для данного шейдера материала.
См. также flags().
[protected] void QSGMaterialShader::setShader(QSGMaterialShader::Stage stage, const QShader &shader)
Устанавливает shader для указанной stage.
[protected] void QSGMaterialShader::setShaderFileName(QSGMaterialShader::Stage stage, const QString &filename)
Устанавливает filename шейдера для указанной stage.
Ожидается, что файл будет содержать сериализованный QShader.
[virtual] bool QSGMaterialShader::updateGraphicsPipelineState(QSGMaterialShader::RenderState &state, QSGMaterialShader::GraphicsPipelineState *ps, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
Этот метод вызывается графической системой сцены, чтобы позволить материалу предоставить настраиваемый набор графических состояний. Набор состояний, настраиваемых материалом, ограничен смешиванием и смежными настройками.
Примечание: Этот метод вызывается только тогда, когда флаг UpdatesGraphicsPipelineState был установлен с помощью setFlags(). По умолчанию он не установлен, и поэтому этот метод никогда не вызывается.
Значение возврата должно быть true всякий раз, когда были внесены изменения в любой из членов в ps.
Примечание: Содержимое ps не сохраняется между вызовами этого метода.
Текущее состояние отрисовки state передаётся графической системой сцены.
Состояние, специфичное для подкласса, можно извлечь из newMaterial. Когда oldMaterial равен null, этот шейдер только что был активирован.
[virtual] void QSGMaterialShader::updateSampledImage(QSGMaterialShader::RenderState &state, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
Этот метод вызывается графической системой сцены для подготовки использования образца изображения в шейдере, обычно в виде комбинированного образца изображения.
binding — номер привязки образца. Метод вызывается для каждой переменной комбинированного образца изображения в коде шейдера, связанного с QSGMaterialShader.
Когда *texture равен null, он должен быть установлен в указатель на QSGTexture перед возвращением. В противном случае материал должен решить, необходимо ли хранить новый QSGTexture * в нём или обновлять некоторые параметры уже известного QSGTexture. Владение QSGTexture не передаётся.
Текущее состояние отрисовки state передаётся графической системой сцены. По мере необходимости, материал должен инициировать помещение в очередь задач загрузки данных текстуры.
Состояние, специфичное для подкласса, можно извлечь из newMaterial.
oldMaterial может использоваться для минимизации изменений. Когда oldMaterial равен null, этот шейдер только что был активирован.
[virtual] bool QSGMaterialShader::updateUniformData(QSGMaterialShader::RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
Этот метод вызывается графической системой сцены, чтобы обновить содержимое буфера униформ программы шейдера. Ожидается, что реализация не будет выполнять никаких реальных графических операций; она просто отвечает за копирование данных в QByteArray, возвращаемый методом RenderState::uniformData(). Графическая система сцены позаботится о том, чтобы этот буфер был виден в шейдерах.
Текущее состояние отрисовки state передаётся графической системой сцены. Если состояние указывает, что какое-либо релевантное состояние является грязным, реализация должна обновить соответствующую область в данных буфера, доступных через RenderState::uniformData(). Если состояние, такое как матрица или непрозрачность, не грязное, нет необходимости трогать соответствующую область, так как данные сохраняются.
Значение возврата должно быть true всякий раз, когда были внесены изменения в данные униформ.
Состояние, специфичное для подкласса, например, цвет плоского цветового материала, должно быть извлечено из newMaterial для обновления соответствующих областей в буфере.
oldMaterial можно использовать для минимизации изменений буфера (которые обычно являются вызовами memcpy) при обновлении состояний материала. Когда oldMaterial равен null, этот шейдер только что был активирован.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.2/qsgmaterialshader.html