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


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

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

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

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

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

Зачем использовать реализации геометрии?

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

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

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

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

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

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

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

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

Создание реализаций геометрии

Необходимо создать объект ID2D1GeometryRealization из существующего объекта ID2D1Geometry . Чтобы создать реализацию геометрии, вызовите метод CreateFilledGeometryRealization или Метод CreateStrokedGeometryRealization и передайте id2D1Geometry для реализации.

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

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

Примечание

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

 

Реализация геометрии рисования

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

Реализация геометрии масштабирования

Реализации geometry, как и другие примитивы 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
        );

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

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

Например, предположим, что приложение никогда не будет масштабировать реализацию геометрии более чем в 2 раз. Ваше приложение может создать реализацию геометрии с помощью сплющений, составляющих половину значения по умолчанию, и просто масштабировать реализацию по мере необходимости до 2 раз. Используйте функцию 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 раз или более), обработка соответствующего масштабирования будет более сложной задачей.

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

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

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

Примечание

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

 

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

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

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

ID2D1DeviceContext1

ID2D1GeometryRealization

Функция ComputeFlatteningTolerance