Класс 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
Когда используется низкоуровневый графический API, 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 не имеет смысла.
END_OF_DOCUMENT_MARKERБэкенд приложения предоставляет 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.1/qsgrendernode.html