[C++] Flash SWF compound shape rasterizer
От: McSeem2 США http://www.antigrain.com
Дата: 13.10.05 16:22
Оценка: 171 (19)
Тема представляет интерес для узкого круга людей, но может кому-то пригодится.

Нарисовать сцену из Flash — задача очень непростая. Несмотря на то, что формат полностью открыт, но я пока что не видел ни одного флаш-плеера (кроме самого Flash), который бы делал все правильно. Дело в том, что формат данных завязан на алгоритм растеризации. Так называемая compound shape состоит не из замкнутых полигонов, закрашенных неким цветом, а из набора ребер с аттрибутами — цвет слева от ребра и цвет справа. Например:



Формат данных для этого примерно таков:
BeginShape()
  BeginPath(left=none, right=green)
    Add Edges 1,2,3,4
  EndPath()
  BeginPath(left=blue, right=none)
    Add Edges 7,8,9,10
  EndPath()
  BeginPath(left=blue, right=green)
    Add Edges 5,6
  EndPath()
EndShape()

Все, никакой другой информации о полигонах нас нет.
Чтобы нарисовать сцену, например при помощи WinAPI PolyPolygon, придется реконструировать замкнутые области в вектороном виде. Это является нетривиальной задачей и возможно даже вообще нерешаемой. Дело в том, что формат допускает некоторые глюки — например, самопересечения, хотя их по идее быть не должно. Оригинальный растеризатор Flash является зверски устойчивым к таким вещам, но добиться этого нелегко. Общая проблема всех попыток воспроизвести самопальный Flash Player — это "горизонтальные протечки".
Думаю, что мне удалось решить проблему устойчивого растаризатора так же надежно, как и Flash. При этом качество
сглаживания — гораздо лучше и возможно даже, что мой растеризатор быстрее работает (но не факт).

А самое главное — модель данных Flash позволяет рисовать смежные области со сглаживанием (anti-alias) и без видимых швов. Но в данном примере это не реализовано — швы видны.

Вот типичная compound shape:


"Нестыковки" — это не глюки алгоритма, оно просто так изначально нарисовано Олегом Куваевым.

Исходник здесь: http://antigrain.com/stuff/agg_flash.zip
Он зависит от AGG, но кому сильно надо — разобраться несложно. Там всего два файла — agg_rasterizer_compound_aa.cpp, agg_rasterizer_compound_aa.h. Ну и маленькая функция рендерера, render_scanlines_compound_solid в flash.cpp.
Для успешной компиляции надо положить, например, в agg23/research/win32/agg_flash/*.*
Файл shapes — это "препарированная" Масяня. Запускаем и нажимаем пробел для рисования следующей compound shape. Навигации назад — нету. Кнопками +/- можно масштабировать относительно курсора. Векторого отсечения тоже нету, поэтому на очень больших масштабах — тормозит.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.