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

Троит картинка при движении объекта


nassl

Вопрос

Не понимаю, как сделать нормальную картинку без смазов при движении.

Ниже простейший код. На форму положен TCircle. Далее по таймеру он двигается. Картинка нечеткая - Circle идет не просто рывками, а двоится и троится.

Пробовал сначала рисовать в буферный Bitmap, потом его разом аккуратно (с   Canvas.BeginScene() и  Canvas.EndScene() по событию OnPaint) рисовал на TRectangle, но картинка та же.
Как правильно под FMX рисовать? 

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects;

type
  TForm1 = class(TForm)
    Circle1: TCircle;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormActivate(Sender: TObject);
begin
Circle1.Position.X:=0;
Circle1.Position.Y:=0;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Circle1.Position.X:=Circle1.Position.X+5;
Circle1.Position.Y:=Circle1.Position.Y+5;
Invalidate();
end;

end.

Такой код не улучшает

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects;

type
  TForm1 = class(TForm)
    Circle1: TCircle;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormActivate(Sender: TObject);
begin
Circle1.Position.X:=0;
Circle1.Position.Y:=0;
end;

procedure TForm1.FormPaint(Sender: TObject; Canvas: TCanvas;
  const ARect: TRectF);
begin
Canvas.BeginScene;
Circle1.Position.X:=Circle1.Position.X+5;
Circle1.Position.Y:=Circle1.Position.Y+5;
Canvas.EndScene;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Invalidate();
end;

end.

1111.jpg

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

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

  • 0
9 часов назад, nassl сказал:

Не понимаю, как сделать нормальную картинку без смазов при движении.

А не смущает заливка формы на Вашем скрине?

Поздравляю, FMX на вашей системе нормально работать не будет (у моих пользователей так бывает, единственное решение которое я нашел - играть с GlobalUseDirect2D := false). Еще нужно обновить драйвера видяхи, но думаю Вы это и так сделали

GlobalUseGPUCanvas тоже может помочь, но вызывает столько новых багов, что лучше не пробовать даже.

А так, вообще, если у вас видяха такая же, как у разработчика FMX, то ничего не троит

procedure TForm24.Timer1Timer(Sender: TObject);
begin
  Circle1.Position.X := Circle1.Position.X + 1;
  Circle1.Position.Y := Circle1.Position.Y + 1;
end;

 

Изменено пользователем Nick Peterson
Ссылка на комментарий
  • 0

Честно говоря, в примере выше смущает все, потому что он толком не работает. Хотя там настройки по умолчанию.  

Как вариант пробовал рисовать на битмапе и копировать его  на канву формы. В таком режиме заливка, вроде, не должна играть роли.  Но эффект тот же. Даже хуже, когда circle перемещается строго горизонтально или вертикально, то более менее нормально картинка идет, но если вбок, то идут искажения по краям в виде лесенки на несколько пикселей, но их видно. 

Причем на телефоне тоже края замазываются.

Буду читать про GlobalUseDirect2D. (Ссылка от склероза https://stackoverrun.com/ru/q/2885822).

Но как можно выкатывать среду разработки, которая на  дефолтных настройках свой же компонент не может по пустрй форме без лагов перерисовать?!

 

 

Изменено пользователем nassl
Ссылка на комментарий
  • 0
28 минут назад, nassl сказал:

Буду читать про GlobalUseDirect2D.

Так а что там читать, просто напишите в dpr файле

  GlobalUseGPUCanvas := false;
  GlobalUseDirect2D := true;
  Application.Initialize;

Полагаю, что это не поможет, тогда попробуйте так

  GlobalUseGPUCanvas := false;
  GlobalUseDirect2D := false;
  Application.Initialize;

Если это поможет, то дальше надо лезить в исходники FMX.Canvas.D2D.pas ...

Ссылка на комментарий
  • 0
  GlobalUseGPUCanvas := false;
  GlobalUseDirect2D := false;

Это не помогло.

 Circle1.Position.X := Circle1.Position.X + 1;
  Circle1.Position.Y := Circle1.Position.Y + 1;

Так нормально стало, но как менять скорость перемещения. 

Если таких кругов много, а двигаются все одним таймером. заводить на каждый круг не выход... 

Ссылка на комментарий
  • 0
3 минуты назад, Nick Peterson сказал:

С одной поправкой - только если железо такое же, как у разработчика FMX

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

Ссылка на комментарий
  • 0
1 минуту назад, Barbanel сказал:

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

Да хоть два

1) см. первое сообщение этой темы

2) Прикладываю.

Угадайте, что на скрине?

image.png.c8cd3721ff3ec42abc82e1c5686e78de.png

(подсказка: это панель с TBevelEffect)

BevelBug.zip

Ссылка на комментарий
  • 0
1 час назад, Nick Peterson сказал:

Да хоть два

1) см. первое сообщение этой темы

2) Прикладываю.

Угадайте, что на скрине?

Подтверждаю.
Баг имеется, причем только в рантайме, в дизайн тайме все рисуется правильно.

Ссылка на комментарий
  • 0
24 минуты назад, krapotkin сказал:

это видеокарта

у меня на 10.3 все гут

так о том и речь

вопрос в том, как уволить из embarcadero сотрудников с таким подходом "у меня все гут, значит проблем нет, можно пускать в релиз"

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

Попробовал воспроизвести проблему у себя (Rio). Но не вышло - не известен интервал вашего таймера, и смущает Circle1.Position.X:=Circle1.Position.X+,  координаты все таки Single, и пытаться делать "движение" без промежуточных кадров - 100% вы получите эффекты стробоскопа.

Сделал изменения в вашем проекте - окружность двигается с возрастающей скоростью по увеличивающейся дуге. В начале движение плавное, но при увеличении дуги и скорости возникает интерференция. Тут надо выбирать между красотой и скоростью. Или писать 3D приложение.

Можете менять значение FSpeed в FormCreate от 1 до 10 - чтоб долго не ждать "разгона".

Вот листинг проекта:

unit Unit25;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Effects, FMX.Controls.Presentation, FMX.StdCtrls,
  FMX.Objects;

type
  TForm25 = class(TForm)
    Circle1: TCircle;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    FSpeed : Integer;
    FIterator : Integer;
    procedure SetPosition(APosition : TPosition);
  end;

var
  Form25: TForm25;

implementation

{$R *.fmx}

procedure TForm25.FormCreate(Sender: TObject);
begin
  FSpeed:= 1;
  FIterator:= 1;
  with Circle1.Position do
  begin
    X:= 0;
    Y:= 0;
  end;
  Timer1.Interval:= 5;
  Timer1.Enabled:= True;
end;

procedure TForm25.SetPosition(APosition : TPosition);
var AValue :extended;
begin
  Inc(FIterator);
  AValue:= -(Pi / 180) * FIterator * FSpeed;
  APosition.X:= ABS(AValue * Cos(AValue));
  APosition.Y:= Abs(AValue * Sin(AValue));
end;

procedure TForm25.Timer1Timer(Sender: TObject);
begin
  SetPosition(Circle1.Position);
end;

end.

 

Ссылка на комментарий
  • 0
3 часа назад, Евгений Корепов сказал:

Попробовал воспроизвести проблему у себя (Rio). Но не вышло - не известен интервал вашего таймера, и смущает Circle1.Position.X:=Circle1.Position.X+ ,  координаты все таки Single, и пытаться делать "движение" без промежуточных кадров - 100% вы получите эффекты стробоскопа.

мой пример максимально упрощен, чтобы обозначить проблему.

интервал таймера 10, координаты, конечно single, но целое число, то в single преобразуется компилятором. 

Про эффект стробоскопа, видимо верно, но там, думаю проблема в самой студии - реально, то я вывожу небольшие битмапы на теперь уже TPainBox, так вот, когда этот битмап перемещается  по диагональным направлениям видны искажения края в виде елочки.

 

 

Ссылка на комментарий
  • 0
2 часа назад, nassl сказал:

видны искажения

Проблема в коде FMX, который не способен справится с нестандартным железом.

P.S. Если только у вас масштаб в винде не 100%, тогда возможно у вас просто смещение неверно задано ( +1 не равно 1 физ. пикселю)

Проверьте 3 варианта (просто напишите в dpr файле). Как минимум в одном из них у вас будут глюки, тогда зайдите на quality.embarcadero.com и опишите глюк, если не затруднит.

Никто этого не делает, воз и ныне там, в новых релизах глюков только больше

  GlobalUseGPUCanvas := false; // true - проверить так и сяк
  GlobalUseDirect2D := true;  // false - проверить так и сяк
  Application.Initialize;
Изменено пользователем Nick Peterson
Ссылка на комментарий
  • 0
5 часов назад, nassl сказал:

мой пример максимально упрощен, чтобы обозначить проблему.

интервал таймера 10, координаты, конечно single, но целое число, то в single преобразуется компилятором. 

Про эффект стробоскопа, видимо верно, но там, думаю проблема в самой студии - реально, то я вывожу небольшие битмапы на теперь уже TPainBox, так вот, когда этот битмап перемещается  по диагональным направлениям видны искажения края в виде елочки.

 

 

В FMX координаты Single и они никак не преобразуются компилятором в Integer. Забудьте о пикселях, они не связаны с координатами. Представьте если бы координаты считались в целых пикселях - сделали вы перемещение под HD монитор, а пользователь запустил приложение на UHD мониторе - все ваши пиксельные расчеты превратятся в тыкву.

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

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

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

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

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

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

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

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

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

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...