Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Мерцание при перерисовке(GDI+) [D7, WinXP]


Страницы:   1 2 3

unknowing ©   (2007-04-24 20:11:00) 

Рисую окружность с рисками через каждые 10 гр, двигаю стрелку по таймеру... И всё это сильно мерцает:(
Как от этого эффекта избавляются профессионалы??
Привожу кусок кода(строго не судить:):

procedure TMainForm.Draw(Count: Smallint);
var
 graphics   : TGPGraphics;
 Pen        : TGPPen;
 SolidBrush : TGPSolidBrush;

 R,
 X, Y,
 Xc,Yc,
 cs, SN,
 cs2, SN2 : Single;
 CountR   : Integer;

const
 dash : array[0..2] of single = (2, 20, 20);
begin

 graphics := TGPGraphics.Create(PaintBox.Canvas.Handle);
 graphics.Clear(clBlack);
 Pen := TGPPen.Create(MakeColor(0, 255, 0),2);  // салатовый
 
 graphics.SetSmoothingMode(SmoothingModeAntiAlias);  

 R :=PaintBox.Height - 80;      //диаметр окружности
 X:= (PaintBox.Width / 2)-R/2;  //координата х левого верхнего угла прямоугольника
 Y:= (PaintBox.Height / 2)-R/2 ;//координата у левого верхнего угла

 graphics.DrawEllipse(Pen, X, Y, R, R);  // окружность

 Xc := X+(R/2);  //координаты центра окружности
 Yc := Y+(R/2);

//---------------------риски румбов----------------------------
 CountR:=0;
  while CountR<360 do
    begin
           Pen.SetWidth(1);
           cs := Xc+(R/2)*cos(CountR*pi/180);  
           sn := Yc+(R/2)*sin(CountR*pi/180);  

           cs2 := Xc+(7+R/2)*cos(CountR*pi/180);  
           sn2 := Yc+(7+R/2)*sin(CountR*pi/180);  

           if frac(CountR/30) = 0 then
            begin  //параметры для толстых рисок
             Pen.SetWidth(3); //
             sn2 := Yc+(10+R/2)*sin(CountR*pi/180);  
            end;
           graphics.DrawLine(pen, cs, sn,cs2,sn2); //рисуем риску

           Inc(CountR,10);
    end;

//---------------------------------------------------------------

//---------------------движение стрелки-----------------------
           Pen.SetWidth(2);
           cs := Xc+(R/2)*cos(Count*pi/180);  
           sn := Yc+(R/2)*sin(Count*pi/180);  

           cs2 := Xc+(R/2 - 15)*cos((10+Count)*pi/180);  
           sn2 := Yc+(R/2 - 15)*sin((10+Count)*pi/180);

           graphics.DrawLine(pen, cs,sn, cs2,sn2);      //стрелка (левая)

           cs2 := Xc+(R/2- 15)*cos((-10+Count)*pi/180);  
           sn2 := Yc+(R/2- 15)*sin((-10+Count)*pi/180);  

           graphics.DrawLine(pen, cs,sn, cs2,sn2);      //стрелка (правая)
//---------------------------------------------------------------

//-----------------------базовые линии окружности-------------
 Pen.SetWidth(0.5);
 Pen.SetDashPattern(@dash, 4);
 graphics.DrawLine(Pen,Xc,Yc-R/2-15,Xc,Yc+R/2+15); //горизонтальная базовая линия окружности
 graphics.DrawLine(Pen,Xc-R/2-15,Yc,Xc+R/2+15,Yc);

//---------------------------------------------------------------
 Pen.Free;
 graphics.Free;
end; //Draw

procedure TMainForm.FormCreate(Sender: TObject);
begin
Count:=0;
end;

procedure TMainForm.Timer1Timer(Sender: TObject);
begin
INC(Count,10);
Draw(Count);
//Timer1.Interval=500;
end;


Unknowing   (2007-05-03 19:35:00) [1]

Всё внимательно прочитал, сделал выводы! Обсуждение закрыто! Всем большое спасибо!!!!


Fenik   (2007-05-03 05:49:00) [2]

> Unknowing ©

Смотри > antonn ©   (02.05.07 21:54) [40]

И первый и второй растры создаются только один раз - при старте. И, соответственно, уничтожаются только одни раз - при завершении работы программы. Внимание, вопрос: кто кого жрет?


antonn   (2007-05-02 21:54:00) [3]


> Если не освобождать каждый раз - жрёт память!

а почему его нужно освобождать все время? он создается раз, при старте.


Unknowing   (2007-05-02 20:39:00) [4]


> Fenik ©   (02.05.07 19:24) [38]

С первым растром понятно, да и давно уже всё работает!.. А со вторым, динамически обновляемым, что делать?? Если не освобождать каждый раз - жрёт память!


Fenik   (2007-05-02 19:24:00) [5]

Блин. Не пойму, в чем проблема, вроде все объяснено
Оптимальный вариант для данной задачи:

1. При запуске приложения (OnCreate формы) создаем два растра одного размера. На первом рисуем циферблат с рисками. Можно даже с градиентом!

2. В событии OnPaint для PaintBox'a (или панели):
1) Копируем с первого растра на второй все содержимое (BitBlt)
2) Рисуем стрелку на втором растре.
3) Копируем второй растр на панель или на PaintBox (или панель) (BitBlt)

3. В OnTimer для таймера вызываем PaintBox.Paint;


Rial   (2007-05-02 18:42:00) [6]

Создавать и уничтожать растр 10 раз в секунду - однозначно глупость.
Исключая какие- то частные, маловероятные в твоем случае ситуации.
И если бы они были, ты бы их наверняка упомянул :)
Вообще, надо выбрать критический параметр и решать задачу
исходя из него. Если слабый процессор - то отыгрываемся на памяти,
если 8 МБ памяти :o) - кушаем процессорное время.


Unknowing   (2007-05-02 17:36:00) [7]

Всем, конечно, спасибо большое за обсуждение! Но я так и непонял: правильно освобождать 10 раз в секунду или нет?? Давайте голосовать!


homm   (2007-04-29 23:12:00) [8]

> Ой... воришка! Наворовал загрузку PNG и своё имя написал.

За слова то отвечать не привык что-ли? Если сам ничего не способен сделать, молчи уже.


Vovan #2   (2007-04-29 22:36:00) [9]

Ой... воришка! Наворовал загрузку PNG и своё имя написал.


Rial   (2007-04-29 22:13:00) [10]

Присоединяюсь к:

> [24] antonn (work)   (29.04.07 16:25)
> homm, просто хочется поспорить?

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


homm   (2007-04-29 21:52:00) [11]

Ну и насчет моих аргументов, если я правда не понятно до этого изъяснялся:
Если это не полноэкранное приложение класса «игра», которуму действительно нужен постоянный буфер, то есть достаточно большая вероятность, что приложение будет достаточно долго не перерисовываться (не важно в следствии чего, свернули его в трей или закрыли другим окном), и тогда память этого приложения потихоньку будет утекать в своп. а когда пользователь снова возжелает лицезреть это приложение, ОС придеться доставать помимо непосредственных рессурсов приложения еще и его экранный буфер, хотя его содержимое не нужно никому. А если приложение и так часто перерисовываеться, то выделить память такого-же размера, как несколько сотен милисекунд назад освобожденная, — системе не доставит труда.


homm   (2007-04-29 21:40:00) [12]

ЗЗЫ Да, насчет «всеми доступными способами» — как ты понимаешь DirectX не в счет ;)


homm   (2007-04-29 21:38:00) [13]

1. Кто же спорит :) Я обоими руками за. И в DablBuffered сам буфер создаеться и уничтожаеться при каждой проприсавке.

2. Создавать растры 25 раз в секунду никто не предлагает! Речь о буфере для вывода!

3. «Ты не хочешь…» Нет, не хочу, я и говорю, что освобождать нужно как только стал не нужен, без дополнительных условий. Идею с освобождением по сворачиванию высказал не я!

4. «тормозить- то будут твои программы» Откопай гденить 500-й селерон с ТНТ видяшкой и 98-м виндовсом, сходи по ссылке, которую  я давал выше, посмотри с какой скоростью рисуются градиенты нехилых размеров со сглажеными краями бордеров и блендингом при наведении :) Попробуй сделать хотя-бы чистый градиент, без сглаженой рамки, всеми доступными способами (да хоть и в 2К) без глюков и правильным отображением в 16 цветах под обе линейки осей, сравни скорость с моей, вот тогда поговорим о тормозах в моих программах :)

ЗЫ «500-й селерон с ТНТ видяшкой и 98-м виндовсом» — это железо, на которых писались эти компоненты :)


Rial   (2007-04-29 21:20:00) [14]

> [28] homm ©   (29.04.07 20:13)
> Делаю то, что считаю нужным. Постараюсь со всеми аргументами
> объяснить человеку, если он ошибатся. А у тебя какие аргументы,
> кроме «Жевал бы лучше» ?

Ок. :)

1. Дабл буфер уменьшает мерцания. По своей сути на скорость
отрисовки он вообще мало влияет. В лучшем случае, она не уменьшится.
Все плюсы идут уже он прямых рук.

2. Вообще глупость какая то. Одно дело светнуто в трей,
другое дело - отрисовка по таймеру, например, в игре.
Создавать растр 25 раз в секунду... лол.
Вообще, что тебе этот трей дался то ?

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

4. Не причислял других подвигов я тебе. Просто преувеличил немного
твои аргументы. И ты сам понял, что они смешные. :)

5. По сути, аргументов не видел как таковых. Главная проблема в том,
что все это - твои проблемы, тормозить- то будут твои программы. %)


homm   (2007-04-29 20:13:00) [15]

> А кривые от того, что опыта работы с графикой фиг да нифига - отсюда

Ну-ну :)

http://homm86.narod.ru/grushcontrols.rar


> Эдакий деятель нашёлся, исправитель кривых рук

Делаю то, что считаю нужным. Постараюсь со всеми аргументами объяснить человеку, если он ошибатся. А у тебя какие аргументы, кроме «Жевал бы лучше» ?


Vovan #2   (2007-04-29 19:52:00) [16]

2 homm:

Жевал бы лучше, а не бред нёс. Эдакий деятель нашёлся, исправитель кривых рук своими же кривыми. А кривые от того, что опыта работы с графикой фиг да нифига - отсюда все эти идиотские ляпы, "ой извините, ошибся" и прочий хлам. Ещё раз говорю - попрограммируй немного, поймёшь что к чему.


homm   (2007-04-29 17:23:00) [17]

> homm, просто хочется поспорить?

Хочется что-бы на свете было как можно меньше кривых программ :) Другие аргументы иссякли, я так понимаяю?


> Тебя послушать, так тогда перед каждым выключением компьютера надо сносить операционку

Хм, интересно где я такое сказал… Не люблю когда мне причисляют чужие подвиги ;)


Rial   (2007-04-29 17:03:00) [18]

> [23] homm ©   (29.04.07 12:44)

Извини конечно, но что за чушь ты несешь ?!
Тебя послушать, так тогда перед каждым выключением компьютера
надо сносить операционку, а потом ее каждое утро заново ставить. %)


antonn (work)   (2007-04-29 16:25:00) [19]

homm, просто хочется поспорить?


homm   (2007-04-29 12:44:00) [20]

> когда приложение в трей свернулось, например...

И сколько ты таких «окончаний необходимости» готов привести? Спорим я все равно на одно больше, да назову, и что ты их все собрался отлавливать, штук так 10 различных ситуаций, когда перерисовка не нужна долгое время, и мы получаем офигенные тормаза по прошествию этого времени, потому что наш битмап ушел в своп? Какие проблемы освобождать память, когда она не понадобиться в ближайшее время? Поверь мне, даже две соседние перерисовки при 10 перерисовках в секунду— не есть «ближайшее время»


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо