Перейти к содержанию
Fire Monkey от А до Я
  • 0

Нарисовать на канве ID2D1RenderTarget (ID2D1Bitmap)


Zyablik3000

Вопрос

Здравствуйте!

Есть самописный компонент - индикатор загрузки написанныый под VCL с использованием Direct2D.

TD2DProgressBar = class(TCustomControl)
FRenderTarget: ID2D1RenderTarget;

FD2DFactory.CreateWicBitmapRenderTarget(FWicBitmap, RenderTargetProp, FRenderTarget);
    FInteropTarget := FRenderTarget as ID2D1GdiInteropRenderTarget;

Вся отрисовка происходит на FRenderTarget.

Затем беру

FInteropTarget.GetDC(D2D1_DC_INITIALIZE_MODE_COPY, FRenderDC);

и вывожу на поверхность функцией
 

procedure TD2DProgressBar.UpdateWindow(sourceDC : HDC);
var
  info : TUpdateLayeredWindowInfo;
begin
  ZeroMemory(@info, sizeof(info));
  with info do begin
    cbSize  := sizeof(TUpdateLayeredWindowInfo);
    pptSrc  := @FSourcePosition;
    pptDst  := @FWindowPosition;
    psize   := @FWndSize;
    pblend  := @FBlend;
    dwFlags := ULW_ALPHA;
  end;
  info.hdcSrc := SourceDC;

  if not UpdateLayeredWindowIndirect(handle, @info) then
  begin
    RaiseLastOSError();
  end

end;

Но это только под VCL.

В Firemonkey не нашел способа комбинировать градиенты и/или нарисовать арку градиентом (саму линию арки а не залить сектор) или комбинацией градиентов.

 

Как вывести этот FRenderTarget на канву Firemonkey-контрола?

Самая большая проблема в том, что компонент полупрозрачный, и вариант с переливом через Vcl.Graphics.TBitmap и MemoryStream не дает нужного результата.
 

MS:=TMemoryStream.Create;

Blend.BlendOp            := AC_SRC_OVER;
Blend.BlendFlags         := 0;
Blend.AlphaFormat        := AC_SRC_NO_PREMULT_ALPHA;
Blend.SourceConstantAlpha:= 255; // // Уровень прозрачности


Res:=Winapi.Windows.AlphaBlend(VCLBitmap.Canvas.Handle, 0, 0, VCLBitmap.Width, VCLBitmap.Height,
                                                              FRenderDC, 0, 0, VCLBitmap.Width, VCLBitmap.Height, Blend);
  {или эта функция

StretchBlt(bm.Canvas.Handle, 0, 0, VCLBitmap.Width, VCLBitmap.Height,
                      FRenderDC, 0, 0, VCLBitmap.Width, VCLBitmap.Height, SRCCOPY); }

VCLBitmap.SaveToStream(MS);

FFMXBitmap.SetSize(TSize.Create(VCLBitmap.Width, VCLBitmap.Height));
FFMXBitmap.LoadFromStream(MS);
FreeAndNil(MS);

 

В Blend пробовал разные комбинации BlendOp и AlphaFormat.

Хелп плизз!

Во вложении компонент под VCL. ( Может кому пригодится)) )

D2DProgressbar.zip

D2DProgressBarImage.jpg

Изменено пользователем Zyablik3000
Ссылка на комментарий

Рекомендуемые сообщения

  • 0

Здравствуйте!

Отвечу сам себе))

Переписал компонент с использованием функционала Firemonkey.

Спасибо за наличие Canvas.ClearRect()

Приложил *.pas, вдруг кому пригодится))

Хотя есть нерешенные проблемы, но о них задам вопросы в других постах.

Однако вопрос про рисование на канве ID2D1RenderTarget остается открытым (хотя-бы с целью повышения образованности).

 

FMXProgress.7z

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...