D2D1RadialGradientBrushProperties(point(0,0), point(0,0), 100, 100),
FRenderTarget.CreateRadialGradientBrush(
D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP,
FRenderTarget.CreateGradientStopCollection(@gStops, 3,
gStops[2] := D2D1GradientStop(1, D2D1ColorF(clBlack, 1));
gStops[1] := D2D1GradientStop(0.7, D2D1ColorF(clBlack, 0.2));
gStops[0] := D2D1GradientStop(0, D2D1ColorF(clWhite, 0));
geometries : array[0..1] of ID2D1EllipseGeometry;
bmrt : ID2D1BitmapRenderTarget;
bob : ID2D1RadialGradientBrush;
gStopsCollection : ID2D1GradientStopCollection;
var gStops : array[0..2] of TD2D1GradientStop;
procedure CreateBubbleOpacityMask();
Здесь в центре нарисована маска. Черным цветом изображены пикселы у которых прозрачность равна нулю, белым - единице. Такая маска накладывается на изображение слева, и после отрисовки на канве белого цвета, получается изображение справа. Приведу полный код создания растровой маски пузыря. Отчасти он повторяет прошлый код, в моментах создания кисти с круговым градентом, и геометрий для эллипса.
ак можно заметить, качество отрисовки значительно страдает. Связано это с тем, что для использования растровой маски необходимо использовать D2D1_ANTIALIAS_MODE_ALIASED в качестве настройки сглаживания. Ведет этом к тому, что сравнение прозрачности происходит попиксельно, и на резкой границе прозрачности у нас получается весьма резкий край. Чтобы замаскировать этот эффект, после отрисовки маски, мы возвращаем режим D2D1_ANTIALIAS_MODE_PER_PRIMITIVE и отрисовываем эллипс, в результате восстанавливая грань (рисуем эллипс, а не закрашиваем). Картинка с :
На самом деле даже не знаю стало ли лучше. Хотя вобще стало, при запуске загрузка процессора около 20 процентов. В прошлый раз было ближе к 40. Что изменилось: ранее для отрисовки пузыря использовались слои, как утверждает документация это сложно и медленно. А у нас в каждом кадре использовалось число слоев по количеству пузырей. Идея оптимизации была в том, что можно использовать маску прозрачности на основе изображения пузыря. Т.е. если раньше мы рисовали пузырь так: брали два эллипса (контур и вложенный), создавали кисть с прозрачностью в центре, заливали оба эллипса градиентом, с использованием маски из этой кисти с помощью слоя, то теперь рисование строится по следующему принципу. В основе пузыря всегда лежит залитый градиентом эллипс. Все что нам надо - наложить на эллипс маску прозрачности. Маска эта будет как и выше строится на основе эллипсов. Но суть в том, что маска такая создается только один раз, и просто применяется, при выводе пузыря. Т.е. слои вообще не используются в коде, даже при создании этой самой маски. Вот тестовая картинка того, как применяется маска. В данном случае растровая маска прозрачности, применена к кругу сплошной заливкой желтого цвета.
В этот раз я попытался ускорить процесс отрисовки пузырей, ибо в все это добросовестно подтормаживало.
Опубликовано 23.08.2011 г. 00:05
Мыльные пузыри в Delphi #3. Растровая маска прозрачности
Delphi programming blog | Мыльные пузыри в Delphi #3. Растровая маска прозрачности
Комментариев нет:
Отправить комментарий