Класс QSGRenderNode
Класс QSGRenderNode представляет собой набор пользовательских команд отрисовки, нацеленных на графический API, используемый в иерархии сцены. Подробнее...
| Заголовок: | #include <QSGRenderNode> |
| CMake: | find_package(Qt6 COMPONENTS Quick REQUIRED) target_link_libraries(mytarget PRIVATE Qt6::Quick) |
| qmake: | QT += quick |
| С момента: | Qt 5.8 |
| Наследует: | QSGNode |
Типы публичного доступа
| перечисление | RenderingFlag { BoundedRectRendering, DepthAwareRendering, OpaqueRendering } |
| флаги | RenderingFlags |
| перечисление | StateFlag { DepthState, StencilState, ScissorState, ColorState, BlendState, …, RenderTargetState } |
| флаги | StateFlags |
Публичные функции
| виртуальный | ~QSGRenderNode() override |
| виртуальный QSGRenderNode::StateFlags | changedStates() const |
| const QSGClipNode * | clipList() const |
| виртуальный QSGRenderNode::RenderingFlags | flags() const |
| qreal | inheritedOpacity() const |
| const QMatrix4x4 * | matrix() const |
| виртуальный void | prepare() |
| виртуальный QRectF | rect() const |
| виртуальный void | releaseResources() |
| виртуальный void | render(const QSGRenderNode::RenderState *state) = 0 |
Подробное описание
Документация по типам членов
перечисление QSGRenderNode::RenderingFlagфлаги QSGRenderNode::RenderingFlags
Возможные значения для битовой маски, возвращаемой функцией flags().
| Константа | Значение | Описание |
|---|---|---|
QSGRenderNode::BoundedRectRendering |
0x01 |
Указывает, что реализация render() не отрисовывает за пределами области, указанной функцией rect() в координатах элемента. Такие реализации узлов могут привести к более эффективной отрисовке в зависимости от бэкэнда иерархии сцены. Например, программный бэкэнд может продолжать использовать более оптимальный путь частичной обновления, если все узлы отрисовки в сцене имеют этот флаг. |
QSGRenderNode::DepthAwareRendering |
0x02 |
Указывает, что реализация render() соответствует ожиданиям иерархии сцены, генерируя только значение Z равное 0 в координатах сцены, которое затем преобразуется матрицами, полученными из RenderState::projectionMatrix() и matrix(), как описано в примечаниях для render(). Такие реализации узлов могут привести к более эффективной отрисовке в зависимости от бэкэнда иерархии сцены. Например, пакетный OpenGL-рендерер может продолжить использовать более оптимальный путь, если все узлы отрисовки в сцене имеют этот флаг. |
QSGRenderNode::OpaqueRendering |
0x04 |
Указывает, что реализация render() записывает непрозрачные пиксели для всей области, указанной функцией rect(). По умолчанию рендеры должны предполагать, что render() может также выводить полупрозрачные или полностью прозрачные пиксели. Установка этого флага может повысить производительность в некоторых случаях. |
Тип RenderingFlags — это псевдоним для QFlags<RenderingFlag>. Он хранит результат побитового ИЛИ комбинации значений RenderingFlag.
перечисление QSGRenderNode::StateFlagфлаги QSGRenderNode::StateFlags
Это перечисление — битовая маска, идентифицирующая несколько состояний.
| Константа | Значение | Описание |
|---|---|---|
QSGRenderNode::DepthState |
0x01 |
Глубина |
QSGRenderNode::StencilState |
0x02 |
Штамп |
QSGRenderNode::ScissorState |
0x04 |
Ножницы |
QSGRenderNode::ColorState |
0x08 |
Цвет |
QSGRenderNode::BlendState |
0x10 |
Смешивание |
QSGRenderNode::CullState |
0x20 |
Обрезка |
QSGRenderNode::ViewportState |
0x40 |
Точка обзора |
QSGRenderNode::RenderTargetState |
0x80 |
Целевая область отрисовки |
Тип StateFlags — это псевдоним для QFlags<StateFlag>. Он хранит результат побитового ИЛИ комбинации значений StateFlag.
Документация по функциям членов
[override virtual] QSGRenderNode::~QSGRenderNode()
Удаляет узел отрисовки. Производные классы должны выполнять очистку, аналогичную releaseResources() в данном методе.
При использовании низкоуровневого графического API иерархия сцены гарантирует ожидание процессора до завершения всех операций, переданных в очередь команд графики иерархии сцены, прежде чем узлы сцены будут удалены. Поэтому нет необходимости в дополнительных ожиданиях, если реализация render() использует дополнительные очереди команд.
См. также releaseResources().
[virtual] QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
При использовании OpenGL эта функция должна возвращать маску, где каждый бит представляет собой изменённые графические состояния функцией render():
- DepthState — маска записи глубины, включение тестирования глубины, функция сравнения глубины
- StencilState — маски записи штампа, включение тестирования штампа, операции штампа, функции сравнения штампа
- ScissorState — включение ножиц, включение тестирования ножиц
- ColorState — цвет очистки, маска записи цвета
- BlendState — включение смешивания, функция смешивания
- CullState — лицевая грань, включение обрезки
- ViewportState — область просмотра
- RenderTargetState — целевая область отрисовки
С другими API, кроме OpenGL, единственно релевантными значениями являются значения, соответствующие динамическим изменениям состояний, записанным в списке/буфере команд. Например, RSSetViewports, RSSetScissorRects, OMSetBlendState, OMSetDepthStencilState в случае D3D11 или vkCmdSetViewport, vkCmdSetScissor, vkCmdSetBlendConstants, vkCmdSetStencilRef в случае Vulkan, и только если такие команды были добавлены в список команд иерархии сцены, запрошенной через ресурс QSGRendererInterface::CommandList. Состояния, заданные в объектах состояния конвейера, не нужно сообщать здесь. Аналогично, настройки, связанные с выводом (состояния конвейера, наборы описателей, привязки буферов вершин или индексов, подпись корня, кучи описателей и т. д.) всегда устанавливаются заново иерархией сцены, чтобы render() мог свободно их изменять.
Примечание: RenderTargetState больше не поддерживается с API, такими как Vulkan. Это по своей сути. render() вызывается, пока основной буфер команд иерархии сцены Qt Quick записывает проход рендеринга, поэтому нет возможности изменить целевую область и начать другой проход рендеринга (по крайней мере в этом буфере команд). Поэтому возвращение значения с установленным RenderTargetState не имеет смысла.
Бэкенд приложения предоставляет QPainter и сохраняет и восстанавливает состояние до и после вызова render(). Поэтому сообщать о любых изменённых состояниях отсюда не требуется.
Функция вызывается рендерером, чтобы он мог сбросить состояние после отрисовки этого узла. Это упрощает реализацию render(), так как ей не нужно запрашивать и восстанавливать эти состояния.
Реализация по умолчанию возвращает 0, что означает, что в render() не было изменено никакого значимого состояния.
Примечание: Эта функция может быть вызвана до render().
const QSGClipNode *QSGRenderNode::clipList() const
Возвращает текущий список обрезки.
[virtual] QSGRenderNode::RenderingFlags QSGRenderNode::flags() const
Возвращает флаги, описывающие поведение этого узла отрисовки.
Реализация по умолчанию возвращает 0.
См. также RenderingFlag и rect().
qreal QSGRenderNode::inheritedOpacity() const
Возвращает текущую эффективную непрозрачность.
const QMatrix4x4 *QSGRenderNode::matrix() const
Возвращает указатель на текущую матрицу модели-представления.
[virtual, since 6.0] void QSGRenderNode::prepare()
Вызывается на фазе подготовки кадра. Перед каждым вызовом render() есть вызов этой функции.
В отличие от render(), эта функция вызывается до того, как граф сцены начинает запись прохода отрисовки для текущего кадра в подлежащий буфер команд. Это полезно при отрисовке с графическими API, такими как Vulkan, где операции типа копирования должны быть записаны до прохода отрисовки.
Реализация по умолчанию пустая.
Эта функция была добавлена в Qt 6.0.
[virtual] QRectF QSGRenderNode::rect() const
Возвращает ограничивающую прямоугольник в координатах элемента для области, с которой render() взаимодействует. Значение используется только тогда, когда flags() включает BoundedRectRendering, в противном случае игнорируется.
Сообщения прямоугольника в сочетании с BoundedRectRendering особенно важно с software бэкендом, потому что в противном случае узел отрисовки в сцене вызовет обновление всего экрана, пропуская все оптимизации частичных обновлений.
Для узлов отрисовки, покрывающих всю область соответствующего QQuickItem, возвращаемое значение будет (0, 0, item->width(), item->height()).
Примечание: Узлы также могут отрисовывать за пределами границ, заданных шириной и высотой элемента, так как узлы графа сцены не ограничены геометрией QQuickItem, при условии, что это правильно сообщается этой функцией.
См. также flags().
[virtual] void QSGRenderNode::releaseResources()
Эта функция вызывается, когда все пользовательские графические ресурсы, выделенные этим узлом, должны быть освобождены немедленно. Если узел не выделяет графические ресурсы (буферы, текстуры, целевые области отрисовки, барьеры и т. д.) напрямую через используемый графический API, здесь ничего делать не нужно.
Невыполнение освобождения всех пользовательских ресурсов может привести к неправильному поведению в ситуациях потери графического устройства на некоторых системах, так как последующая повторная инициализация графической системы может завершиться ошибкой.
Примечание: Некоторые бэкэнды графа сцены могут выбрать не вызывать эту функцию. Поэтому ожидается, что реализации QSGRenderNode будут выполнять очистку как в своём деструкторе, так и в releaseResources().
В отличие от деструктора, ожидается, что render() может повторно инициализировать все необходимые ресурсы при вызове после вызова releaseResources().
С OpenGL контекст OpenGL графа сцены будет текущим как при вызове деструктора, так и при вызове этой функции.
[pure virtual] void QSGRenderNode::render(const QSGRenderNode::RenderState *state)
Эта функция вызывается рендерером и должна отрисовать этот узел, напрямую вызывая команды в используемом графическом API (OpenGL, Direct3D и т. д.).
Эффективную непрозрачность можно получить с помощью inheritedOpacity().
Матрица проекции доступна через state, а матрицу модели-представления можно получить с помощью matrix(). Объединённая матрица — это произведение матрицы проекции на матрицу модели-представления. Правильная организация элементов в сцене обеспечивается матрицей проекции.
При использовании предоставленных матриц система координат для данных вершин следует обычным соглашениям QQuickItem: верхний левый угол — (0, 0), нижний правый угол — соответствующая ширина() и высота() QQuickItem минус единица. Например, предполагая макет из двух float (x-y) на вершину, треугольник, покрывающий половину элемента, можно указать как (width - 1, height - 1), (0, 0), (0, height - 1) по часовой стрелке.
Примечание: QSGRenderNode предоставлен как средство реализации пользовательских 2D или 2.5D элементов Qt Quick. Он не предназначен для интеграции истинного 3D-контента в сцену Qt Quick. Для этого лучше подходит QQuickFramebufferObject, QQuickWindow::beforeRendering() или их аналоги для API, отличных от OpenGL.
Примечание: QSGRenderNode может работать значительно лучше, чем подходы на основе текстур (такие как QQuickFramebufferObject), особенно на системах с ограниченной мощностью обработки фрагментов. Это потому, что он избегает отрисовки в текстуру и последующего рисования текстурированного квадрата. Вместо этого QSGRenderNode позволяет записывать вызовы рисования вместе с другими командами графа сцены, избегая дополнительной целевой области отрисовки и потенциально дорогостоящей текстурирования и смешивания.
Информация об обрезке рассчитывается до вызова функции. Реализации, желающие учесть обрезку, могут настроить цитрирование или на основе маски с учётом информации в state. Буфер маски заполняется необходимыми формами обрезки, но реализация должна включить проверку маски.
Некоторые бэкэнды графа сцены, в частности программные, не используют цитрирование или маску. В этом случае область обрезки предоставляется как обычная QRegion.
С устаревшем рендерере, основанном на OpenGL, следующие состояния устанавливаются на контексте потока отрисовки перед вызовом этой функции:
- glColorMask(true, true, true, true)
- glDepthMask(false)
- glDisable(GL_DEPTH_TEST)
- glStencilFunc(GL_EQUAL, state.stencilValue, 0xff); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP) в зависимости от обрезки
- glScissor(state.scissorRect.x(), state.scissorRect.y(), state.scissorRect.width(), state.scissorRect.height()) в зависимости от обрезки
- glEnable(GL_BLEND)
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
- glDisable(GL_CULL_FACE)
Состояния, которые не перечислены выше, но покрываются StateFlags, могут иметь произвольные значения.
Примечание: Для других графических API состояние не устанавливается, принимая во внимание, что многие из них не имеют понятия о традиционной машинной модели состояния OpenGL. Вместо этого реализация должна создать объекты состояния конвейера с включёнными желаемыми блендингом, цитрированием и проверками маски. Это также включает OpenGL через RHI. Новым реализациям QSGRenderNode рекомендуется явно устанавливать все состояния цитрирования, маски и блендинга (как показано в списке выше), даже если они предназначены для OpenGL.
changedStates() должно возвращать, какие состояния изменяются этой функцией. Если состояние не покрывается StateFlags, состояние должно быть установлено в значение по умолчанию в соответствии со спецификацией OpenGL. Для других API см. документацию по changedStates() для получения дополнительной информации.
Примечание: Запись в буфер глубины отключена при вызове этой функции (glDepthMask(false) с OpenGL). Включение записи в буфер глубины может привести к непредсказуемым результатам в зависимости от используемого бэкэнда графа сцены и содержимого сцены, поэтому будьте осторожны с этим.
Для API, отличных от OpenGL, скорее всего, потребуется запрос определённых ресурсов, специфичных для API (например, графического устройства или списка/буфера команд для добавления команд). Это выполняется через QSGRendererInterface.
Не предполагайте ничего о связанных конвейерах и динамических состояниях в списке/буфере команд при вызове этой функции.
Для некоторых графических API может быть необходимо подключиться к сигналу QQuickWindow::beforeRendering(), потому что этот сигнал испускается перед записью начала прохода отрисовки в буфер команд (vkCmdBeginRenderPass с Vulkan или начало кодирования через MTLRenderCommandEncoder в случае Metal). Запись операций копирования не может быть выполнена внутри render() с такими API. Вместо этого сделайте это в слоте, подключённом (с DirectConnection) к сигналу beforeRendering.
См. также QSGRendererInterface и QQuickWindow::rendererInterface().
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.0/qsgrendernode.html