Поделиться через


Обзор реализаций геометрии

В этом разделе описывается, как использовать реализации геометрии Direct2D для повышения производительности отрисовки геометрии приложения в определённых сценариях.

Он содержит следующие разделы:

Что такое геометрическая реализация?

Реализация геометрии, представленная в Windows 8.1, — это новый тип примитива рисования, который упрощает приложения Direct2D для повышения производительности геометрической отрисовки в определенных случаях. Реализации геометрии представлены интерфейсом ID2D1GeometryRealization.

Почему используются реализации геометрии?

Когда Direct2D отрисовывает объект ID2D1Geometry, он должен преобразовать эту геометрию в форму, которую графическое оборудование понимает через процесс, называемый тесселяцией. Как правило, Direct2D должен выполнять тесселяцию геометрии каждый кадр, когда она рисуется, даже если геометрия не изменяется. Если ваше приложение отрисовывает одну и ту же геометрию в каждом кадре, то повторная ретесселяция представляет напрасно затраченные вычислительные ресурсы. Более эффективно с вычислительной точки зрения кэшировать тесселяцию или даже полную растеризацию геометрии и отрисовывать это кэшированное представление каждого кадра вместо многократной повторной тесселяции.

Распространенный способ, которым разработчики решают эту проблему, заключается в кэшировании полной растеризации геометрии. В частности, обычно создается новое растровое изображение, выполняется растеризация геометрии в это изображение, а затем оно отображается на сцене при необходимости. (Этот подход описан в разделе отображения геометрии улучшения производительности приложений Direct2D.) Хотя этот подход очень эффективен для вычислений, он имеет некоторые недостатки:

  • Кэшированное растровое изображение учитывает изменения преобразования, примененного к сцене. Например, масштабирование растеризации может привести к заметным артефактам масштабирования. Устранение этих артефактов с использованием высококачественных алгоритмов масштабирования может требовать значительных вычислительных ресурсов.
  • Кэшированное бинарное изображение потребляет значительный объем памяти, особенно если оно растеризовано при высоком разрешении.

Реализация геометрии обеспечивает альтернативный способ кэширования геометрии, который позволяет избежать указанных выше недостатков. Реализация геометрии представлена не пикселями (как и в случае с полной растеризацией), а вместо этого точками на математической плоскости. По этой причине они менее чувствительны, чем полные растеризации для масштабирования и других манипуляций, и они потребляют значительно меньше памяти.

Когда следует использовать геометрическую реализацию

Рассмотрите возможность использования геометрических реализаций, когда приложение отрисовывает сложные геометрии, фигуры которых изменяются редко, но могут быть подвержены изменению преобразований.

Например, рассмотрим картографическое приложение, показывающее статическую карту, но позволяющее пользователю приближать и отдалять масштаб. Это приложение может использовать геометрические реализации. Так как отрисовываемые геометрии остаются статическими, их полезно кэшировать, чтобы сохранить работу тесселяции. Но поскольку карты изменяются в масштабе при увеличении пользователем, кэширование полной растризации не является оптимальным из-за артефактов масштабирования. Кэширование геометрических структур позволит приложению избежать повторных задач тесселяции с сохранением высокого визуального качества при масштабировании.

С другой стороны, рассмотрим приложение kaleidoscope с анимированной геометрией, которая постоянно изменяется. Это приложение, вероятно, не извлечет пользу из использования геометрии. Так как фигуры сами изменяются с кадра на кадр, нет смысла кэшировать их тесселяции. Лучшим подходом для этого приложения является рисование объектов ID2D1Geometry напрямую.

Создание геометрических реализаций

Объект ID2D1GeometryRealization должен быть создан из существующего объекта ID2D1Geometry. Чтобы создать реализацию геометрии, вызовите метод CreateFilledGeometryRealization или метод CreateStrokedGeometryRealization и передайте ID2D1Geometry, которую нужно реализовать.

Оба типа реализации геометрии представлены интерфейсом ID2D1GeometryRealization.

При создании реализации геометрии Direct2D должен сравнять все кривые в предоставленной геометрии в многоугольные приближения. Для метода создания необходимо предоставить параметр допусков выравнивания — он определяет максимальное расстояние в независимых от устройства пикселях (DIPs) между истинной кривой геометрии и её полигональной аппроксимацией. Чем ниже значение допуска на уплощение, тем выше точность соответствия результирующего объекта представления геометрии. Аналогичным образом, обеспечивая большую допустимую деформацию, получают менее точную реализацию геометрии. Обратите внимание, что геометрические представления с более высокой точностью требуют больше ресурсов для отрисовки, чем модели с более низкой детализацией, но их можно масштабировать дальше, прежде чем они приведут к появлению видимых артефактов. Рекомендации по использованию неструктурированных допустимых разрешений см. в реализации геометрии масштабирования ниже.

Заметка

Объекты реализации геометрии связаны с определенным графическим устройством: они являются ресурсами, зависящими от устройств.

 

Реализация геометрических построений

Построение геометрических объектов похоже на рисование других Direct2D примитивов, таких как растровые изображения. Для этого вызовите метод DrawGeometryRealization и передайте в него объект реализации геометрии, который необходимо нарисовать, и кисть для этого. Как и в других методах рисования Direct2D, необходимо вызывать DrawGeometryRealization между вызовами BeginDraw и EndDraw.

Масштабирование геометрических реализаций

Реализации геометрии, как и другие Direct2D примитивы, учитывают установленные преобразования в контексте устройства. Хотя преобразования сдвига и поворота не влияют на визуальное качество геометрии, преобразования масштабирования могут создавать визуальные артефакты.

В частности, применение достаточно большого масштаба к любой реализации геометрии может выявить многоугольнальное приближение истинных кривых. На изображении показана пара вариантов эллиптической геометрии (заливка и обводка), которые были чрезмерно увеличены в масштабе. Видны артефакты выравнивания кривой.

пара эллиптических геометрических реализаций (заливки и обводки), которые были масштабированы слишком сильно. Артефакты сглаживания кривых видны.

Приложения, чувствительные к качеству визуального элемента, должны принимать меры, чтобы это не произошло. Обработка масштабирования зависит от потребностей приложения. Ниже приведены несколько рекомендуемых подходов для нескольких различных типов приложений.

Использование геометрических представлений в приложениях, которые не масштабируются

Если ваше приложение не выполняет масштабирование реализаций геометрии, то безопасно создать реализации только один раз, используя один допуск сглаживания. (Преобразования, не относящиеся к масштабированию, не влияют на визуальное качество отрисованных реализаций геометрии.) Используйте функцию ComputeFlatteningTolerance для вычисления соответствующего допуска упрощения для DPI:

    float dpiX, dpiY;
    deviceContext->GetDpi(&dpiX, &dpiY);

    float flatteningTolerance = D2D1::ComputeFlatteningTolerance(
        D2D1::Matrix3x2F::Identity(),   // apply no additional scaling transform
        dpiX,                           // horizontal DPI
        dpiY                            // vertical DPI
        );

Использование геометрических реализаций в приложениях, масштабируемых на небольшую величину

Если ваше приложение может масштабировать реализацию геометрии только на небольшой коэффициент (например, до 2x или 3x), то целесообразно просто создать реализацию геометрии один раз, с пропорционально меньшим допуском упрощения, чем по умолчанию. Это создает реализацию с более высоким качеством, которая может значительно увеличиваться в масштабе, пока не появятся артефакты масштабирования; компромисс в том, что создание реализации с более высоким качеством требует больше усилий.

Например, предположим, что приложение никогда не будет масштабировать геометрическую реализацию более чем на 2x. Ваше приложение может создать геометрическую реализацию с помощью допуска на расплющивание, равного половине значения по умолчанию, и просто масштабировать реализацию по мере необходимости, увеличивая ее вдвое. Используйте функцию ComputeFlatteningTolerance для вычисления подходящей точности упрощения, передав 2.0 в качестве параметра maxZoomFactor.

    float dpiX, dpiY;
    deviceContext->GetDpi(&dpiX, &dpiY);
    
    float flatteningTolerance = D2D1::ComputeFlatteningTolerance(
        D2D1::Matrix3x2F::Identity(),   // apply no additional scaling transform
        dpiX,                           // horizontal DPI
        dpiY,                           // vertical DPI
        2.0f                            // realization can be scaled by an additional 2x
        );

Использование геометрических реализаций в приложениях, масштабируемых в значительной степени

Если ваше приложение может существенно масштабировать геометрическую реализацию вверх или вниз (например, в 10 раз или более), тогда обработка масштабирования станет сложнее.

Для большинства этих приложений рекомендуемый подход — воссоздать геометрическую реализацию при постепенно более низких допусках выравнивания по мере масштабирования сцены, чтобы обеспечить визуальное качество и избежать масштабирования артефактов. Аналогичным образом, когда сцена уменьшается в масштабе, приложение должно воссоздавать геометрические реализации с постепенно увеличивающимися допусками сглаживания, чтобы избежать расточительной отрисовки деталей, которые не видны. Приложение не должно воссоздавать геометрические реализации каждый раз при изменении масштаба, так как это сводит на нет смысл кэширования задачи тесселяции. Вместо этого приложение должно воссоздавать реализацию геометрии реже: например, каждые 2x увеличения или уменьшения масштаба.

При каждом изменении масштаба в приложении в ответ на взаимодействие с пользователем приложение может сравнить новый масштаб с масштабом, с которыми были созданы последние реализации геометрии (например, в элементе m_lastScale). Если два значения близки (в данном случае в пределах 2), дальнейшие действия не выполняются. Но если два значения не близки, то геометрические реализации создаются заново. Функция ComputeFlatteningTolerance используется для вычисления допуска упрощения, соответствующего новому масштабу, и m_lastScale обновляется на новый масштаб.

Кроме того, приложение всегда создает реализации с помощью меньшей допустимости, чем обычно используется для нового масштаба, передав значение 2 в качестве параметра maxZoomFactor для ComputeFlatteningTolerance. Это позволяет масштабировать новые реализации геометрии с помощью дополнительного коэффициента 2 без применения артефактов масштабирования.

Заметка

Описанный здесь подход может не соответствовать всем приложениям. Например, если приложение позволяет масштабировать сцену очень большими факторами очень быстро (например, если оно содержит ползунок "масштаб", который можно переместить с 100% до 1 000 000% в диапазоне нескольких кадров), то такой подход может привести к избыточной работе из-за повторного создания представлений геометрии в каждом кадре. Альтернативный подход заключается в том, чтобы воссоздавать геометрические реализации только после завершения каждой манипуляции с масштабом сцены (например, после того, как пользователь завершил жест щипка).

 

Обзор геометрии

повышение производительности приложений Direct2D

Общие рекомендации по отрисовке сложного статического содержимого

ID2D1DeviceContext1

ID2D1GeometryRealization

функция "ВычислитьДопускВыравнивания"