• 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 ответов на этот вопрос

  • 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

эмм, а насчет рисовать на специально выделенных местах - не на форме а на PaintBox никак?

там все без бубнов взлетает

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

У меня, качество картинки на этом пробном коде не меняется при рисовании на painbox.

(железо i5-8600k, gtx 1600, win10 ) 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 23.01.2019 в 09:16, krapotkin сказал:

там все без бубнов взлетает

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 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 мониторе - все ваши пиксельные расчеты превратятся в тыкву.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

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

Войти

Уже есть аккаунт? Войти в систему.

Войти

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

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