Класс 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 |
Функции публичного доступа
| virtual | ~QSGRenderNode() override |
| virtual QSGRenderNode::StateFlags | changedStates() const |
| const QSGClipNode * | clipList() const |
| virtual QSGRenderNode::RenderingFlags | flags() const |
| qreal | inheritedOpacity() const |
| const QMatrix4x4 * | matrix() const |
| virtual void | prepare() |
| virtual QRectF | rect() const |
| virtual void | releaseResources() |
| virtual 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 в качестве основного API эта функция должна возвращать маску, где каждый бит представляет измененные графические состояния, заданные функцией 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, поэтому нет возможности изменить целевой объект и начать новый renderpass (по крайней мере, в этом буфере команд). Поэтому возвращение значения с 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 минус единица. Например, предположив макет с двумя плавающими числами (x-y) на вершину, треугольник, покрывающий половину элемента, можно указать как (ширина - 1, высота - 1), (0, 0), (0, высота - 1) по часовой стрелке.
Примечание: QSGRenderNode предоставляется как средство для реализации пользовательских элементов Qt Quick 2D или 2.5D. Он не предназначен для интеграции истинно 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.2/qsgrendernode.html