Модераторы: Snowy, Alexeis, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> GDI+, Direct2D, firemonkey и все все все 
:(
    Опции темы
Alexeis
Дата 31.5.2013, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 55
Всего: 459



Цитата(gonzales @  30.5.2013,  22:37 Найти цитируемый пост)
я правильно понимаю, что я должен вызвать InvalidateRect для всей области моего контрола и тем самым вызвать OnPaint?


  Неа, только для области под курсором. Если можно перерисовывать не все то желательно так и делать. 
Цитата(gonzales @  30.5.2013,  22:37 Найти цитируемый пост)
Кстати, SetDIBitsToDevice предполагает конвертацию из TBitmap в DIB, не даст ли это обратный эффект

  Эмм.. насколько я понимаю TBitmap это и есть DIB . По крайней мере TBitmap может быть DIB если ему установить PixelFormat . По идее, получается прямое рисование DIB на контекст безо всякого копирования.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
gonzales
Дата 31.5.2013, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 241
Регистрация: 13.3.2006

Репутация: 1
Всего: 2



что то я совсем запутался, окончательно и бесповоротно((((((((
сделал я SetDIBitsToDevice все одно, пока repaint или refrash не вызову, изображение на экране не перерисовывается. 
перекрыл событие Paint для моего наследника TImage, написал банальное
Код

procedure TFrameImage.Paint;
begin
 inherited;
 showmessage('1');
end;

получаю 4 мессаджбокса, хотя процедура перерисовки DrawImage вызывалась 1 раз. Это может быть из-за того, что во время перерисовки на экране появляется вторая форма, частично закрывающая мой контрол?

Если я пишу 
Код

procedure TFrameImage.Paint;
begin
 inherited;
 DrawImage;
end;


то все навеки зависает.

Может я свойство какое у TImage не заполняю, что он так себя ведет?

Практически все реализовано как в примере AvgChart. Только там используется TCustomControl, а у меня TImage. 

убираю из функции DrawImage repaint и fps на уровне 50, но отрисовка идет не плавно а большими рывками, ставлю repaint, fps падает до 7 но отрисовка гораздо плавнее.(((




--------------------
- мастер, мастер, запорол..., все четыре запорол!!!- я ж тебе только три давал!!!???- да я и образец запорол!!!!
PM MAIL   Вверх
Beltar
Дата 31.5.2013, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 1
Всего: 7



Между TImage и TCustomControl есть одно отличие, TImage не имеет дескриптора. Я, правда, не помню сейчас, почему я использовал именно TCustomControl, а не TGraphicControl, но что-то меня там не устроило. В принципе есть еще и компонент TPaintBox, Но это тоже GraphicControl. Попробуй тоже TCustomControl заюзать.

Paint должен вызываться автоматически при любой перерисовке, разворачивание окна, закрытие его части и т. п. Я не вижу смысла вызывать методы перерисовки кроме Refresh вручную.

Как ты fps мерял? В играх средне fps измеряется из-за непрерывности цикла отрисовки, тут-то цикла нету.

Это сообщение отредактировал(а) Beltar - 31.5.2013, 20:09


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
gonzales
Дата 1.6.2013, 12:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 241
Регистрация: 13.3.2006

Репутация: 1
Всего: 2



а у tcustomcontrol у меня возникли проблемы с прозрачным canvas. Изначально я и хотел сделать из TCustomControl контейнер, в который положить несколько TImage, которые будут как бы слоями с изображениями, но не смог добиться прозрачного фона. TImage уже предполагает работу с прозрачностью, поэтому я его и выбрал.
А fps меряю просто. Замеряю кол-во тактов в начале процедуры и в конце, делю на частоту процессора, получаю время работы процедуры. Ну а fps - это будет 1/время. Это конечно не средне-статистическое значение, но приблизительное представление оно дает, по крайней мере порядок величины.

Добавлено через 5 минут и 48 секунд
Цитата

Я не вижу смысла вызывать методы перерисовки кроме Refresh вручную.

как раз приходится вызывать вручную, чтобы избежать ненужных прорисовок объектов, когда из например частично перекрывают другие объекты. если я запихну процедуру отрисовки объекта в Paint то при любом перекрытии объекта он будет перерисован, хотя с ним никаких изменений не происводилось. 
--------------------
- мастер, мастер, запорол..., все четыре запорол!!!- я ж тебе только три давал!!!???- да я и образец запорол!!!!
PM MAIL   Вверх
Beltar
Дата 1.6.2013, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 1
Всего: 7



Как-то слишком сложно. Если у тебя там нет непрерывной анимации, то для замера времени будет достаточно GetTickCount. Можно Stopwatch, т. к. GetTickCount дает значения с шагом 16. Но если у тебя рисуется за 100 мс, то тебе и этой точности хватит для оценки лага. Если есть анимация, то лучше заюзать Сфинкса и не думать о таймерах, 2D-графику он тебе даже на нетбуке, скорее всего, вытащит. Избыточные вычисления, если на сотни fps шпарить будет, забирая ядро целиком можно подавить ограничением fps. Да и фотошопы вроде уже давно за счет аппаратной отрисовки живут.

Заблокировать отрисовку можно просто добавив какое-то условие в ф-ию отрисовки, или в Paint перед ее вызовом. Сам вызов Paint ты не можешь контролировать, если приложение свернули, а затем развернули, то Paint будет вызван. Но вот само условие блокировки рисовки будет весьма нетривиальным. У меня в AvgChart ручной вызов перерисовки делается только в том случае, если были изменены данные и то можно с помощью BeginUpdate перекрыть это дело.

Опиши лучше, что рисуешь и в каком порядке. Не исключено, что и саму Paint можно свести к тупому вызову BitBlt, или как она там на канвасе, Draw вроде, а сложную часть запоминать на битмепе и уже ее перерисовывать вручную, если, например, добавился объект, или был сделан ресайз контрола.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
Alexeis
Дата 1.6.2013, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 55
Всего: 459



Цитата(gonzales @  31.5.2013,  17:30 Найти цитируемый пост)
Может я свойство какое у TImage не заполняю, что он так себя ведет?

  TImage лучше совсем не трогать по вопросам сообщений. Надежнее обращаться к окну которое лежит ниже. Я бы вообще не использовал TImage. Этот класс предназначен для статических изображений. Эффективнее выводить графику прям на окно. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
gonzales
Дата 3.6.2013, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 241
Регистрация: 13.3.2006

Репутация: 1
Всего: 2



заменил repaint на paint, отрисовка заработала на несколько порядков быстрей, НО Paint не стирает содержимое а рисует поверх. Как в перекрытом методе Paint заставить его стереть изображение?

Рисую графический фрейм для изображения. см рисунок.
создаю его на основе TImage. прописал функции mousedown, mousemove, mouseup и drawimage.

По событиям мыши производятся все координатные вычисления, затем вызывается drawimage.


Код

constructor TFrameImage.Create(aowner: Tcomponent); // конструктор
begin
inherited Create(aowner);
//создаю буферный битмап
  bufbtm:=TBitmap.Create;
  bufbtm.PixelFormat:=pf32bit;
  bufbtm.Width:=width;
  bufbtm.Height:=height;
end;

procedure TFrameImage.FrameImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
begin
//вычисляю в какую точку фрейма ткнул пользователь
//присваиваю флаг
mouseclickflag:= 
end;

procedure TFrameImage.FrameImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: integer);
begin
//вычисляю новую геометрию фрейма
DrawImage;
end;

procedure TFrameImage.FrameImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: integer);
begin
 mouseclickflag := clno;
 DrawImage(true, Fdpi_limit);
end;

procedure TFrameImage.DrawImage;
begin
//рисую на канве контрола или на канве буферного битмапа
graphicsGDIPlus := TGPGraphics.Create({bufbtm.}canvas.Handle);
//-----
//--функции отрисовки---
//-----
// далее необходимо обновить контрол, чтобы изображение из буфера видеокарты отобразилось на экране
Repaint; //---> просадка fps
Paint; //----> зависает
end;

procedure TFrameImage.Paint;
begin
 inherited;
 canvas.Draw(0,0,bufbtm);  //если рисую на канве буферного битмапа вывожу его на экран.
end;







Присоединённый файл ( Кол-во скачиваний: 9 )
Присоединённый файл  Снимок.JPG 38,22 Kb
--------------------
- мастер, мастер, запорол..., все четыре запорол!!!- я ж тебе только три давал!!!???- да я и образец запорол!!!!
PM MAIL   Вверх
gonzales
Дата 3.6.2013, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 241
Регистрация: 13.3.2006

Репутация: 1
Всего: 2



пробую внедрить флаг перерисовки, все равно канва не очищается
Код

procedure TFrameImage.Paint;
begin

 if paintflag=true then
  begin
 InValidateRect(Canvas.Handle,nil,true);
 Canvas.FillRect(Canvas.ClipRect);
 canvas.Draw(0,0,bufbtm);
 paintflag:=false;
  end;
 inherited;
end;


Это сообщение отредактировал(а) gonzales - 3.6.2013, 13:45
--------------------
- мастер, мастер, запорол..., все четыре запорол!!!- я ж тебе только три давал!!!???- да я и образец запорол!!!!
PM MAIL   Вверх
Beltar
Дата 3.6.2013, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 1
Всего: 7



А она и не будет очищаться, просто залей ее цветом фона перед рисованием.

Код

Paint; //----> зависает


Говорю же, Paint вызывается автоматически.

Должно быть

Код

procedure Paint;
begin
inherited;
DrawImage;
end;


Ты сейчас все запутываешь только. В DrawImage должно быть описано как рисовать, а не когда. Для этого программа сама когда нужно Paint вызовет.

Вот у тебя на картинке рамка, ты за нее явно тянешь. У тебя только рамка тянется или само изображение тут же перерисовывается? Если только рамка, то кто мешает хранить изображение на битмепе, перерисовывая только разметку, как у меня с графиком и делается?


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
gonzales
Дата 3.6.2013, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 241
Регистрация: 13.3.2006

Репутация: 1
Всего: 2



Код

Вот у тебя на картинке рамка, ты за нее явно тянешь. У тебя только рамка тянется или само изображение тут же перерисовывается? 

изображение тоже пееррисовывается.

Цитата

Ты сейчас все запутываешь только. В DrawImage должно быть описано как рисовать, а не когда.

Так у меня и описано. А когда перерисовывать решают события мыши. 

Я убрал явный вызов drawImage из событий мыши и написал
Код

procedure Paint;
begin
inherited;
DrawImage;
 Canvas.FillRect(Canvas.ClipRect);
 canvas.CopyRect(rect(0,0,width,height),bufbtm.Canvas,rect(0,0,width,height));
end;


и получил висяк, у меня бесконечно вызывается Paint, что вообще логично, получается рекурсия. 

Цитата

А она и не будет очищаться, просто залей ее цветом фона перед рисованием.

так я заливаю
Canvas.FillRect(Canvas.ClipRect);
и все равно не очищается.

--------------------
- мастер, мастер, запорол..., все четыре запорол!!!- я ж тебе только три давал!!!???- да я и образец запорол!!!!
PM MAIL   Вверх
gonzales
Дата 3.6.2013, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 241
Регистрация: 13.3.2006

Репутация: 1
Всего: 2



я не понимаю как у тебя в примере все работает
Код

procedure TAvgChart.Paint;
begin
  inherited;
Draw;  // рисование
end;

procedure TAvgChart.Draw;
var T:Cardinal;
begin
if BlockPaint then Exit;
DoBeforeReapint;
T:=GetTickCount;
DeltaX:=FMaxXValue-FMinXValue;//глобальный DeltaX, для ValueToPoint
DrawZoneX:=Width-LeftBorder-RightBorder;
DrawZoneY:=Height-TopBorder-BottomBorder;
DrawTrends;
FastRepaint;//Дорисовка
FDrawTime:=GetTickCount-T;
DoAfterRepaint;
end;

procedure TAvgChart.FastRepaint;
begin
if BlockPaint then Exit;
Canvas.Pen.Mode:=pmCopy;
if Assigned(Bmp1) then Bmp1.Free;
Bmp1:=TBitmap.Create;
Bmp1.Width:=Width;
Bmp1.Height:=Height;
Bmp1.Canvas.Draw(0,0,Bmp);
if FSetsRectangles then DrawRectangles;
DrawAxes;
DrawValueLines;
if FInSelection then DrawSelection;
Canvas.Draw(0,0,Bmp1);
end;



у тебя по paint вызывается draw, в котором сидит fastrepaint, в котором изменяется канва Canvas.Draw(0,0,Bmp1);
соответственно опять должно автоматически вызваться Paint и опять же рекурсия. Но я так понимаю, этого не происходит. Можешь объяснить, почему?
--------------------
- мастер, мастер, запорол..., все четыре запорол!!!- я ж тебе только три давал!!!???- да я и образец запорол!!!!
PM MAIL   Вверх
Beltar
Дата 3.6.2013, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 1
Всего: 7



Зачем? Paint вызывается или автоматом, когда контролу надо перерисоваться (типичный случай, разворот приложения, или изменение размеров контрола), или если контролу был сделан принудительный Refresh. Но к низкоуровневым функциям, которые переводят байты канваса в пиксели монитора она никакого отношения не имеет. У TCustomControl Paint ЕМНИП вообще пустая. Обработка мыши у меня прописана в самом контроле и вызывает только быструю упрощенную прорисовку. Попросту Paint это метод, который должен осуществлять полную прорисовку по умолчанию.

В твоем случае рисование тоже разделяется на 2 части: сами картинки и пользовательская разметка.

http://biblioteka.cc/index.php?newsid=30955 стр 75. ЕМНИП Repaint как раз и вызывает Paint.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
gonzales
Дата 5.6.2013, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 241
Регистрация: 13.3.2006

Репутация: 1
Всего: 2



Цитата

Но к низкоуровневым функциям, которые переводят байты канваса в пиксели монитора она никакого отношения не имеет.

если не имеет, то я не понимаю, почему у меня все время вызывается paint, если я использую 
Код

procedure Paint;
begin
inherited;
DrawImage;
end;


получается у меня где-то в drawimage вызывается paint?
--------------------
- мастер, мастер, запорол..., все четыре запорол!!!- я ж тебе только три давал!!!???- да я и образец запорол!!!!
PM MAIL   Вверх
gonzales
Дата 5.6.2013, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 241
Регистрация: 13.3.2006

Репутация: 1
Всего: 2



НАШЕЛ!!!
методом научного тыка выяснил
функция Canvas.FillRect(Canvas.ClipRect); в DrawImage вызывает Paint
осталось понять, как очистить канву не используя FillRect


--------------------
- мастер, мастер, запорол..., все четыре запорол!!!- я ж тебе только три давал!!!???- да я и образец запорол!!!!
PM MAIL   Вверх
Beltar
Дата 5.6.2013, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 1
Всего: 7



А ты там брейкпойнт не ставишь, так что приложение переключается нна IDE, а потом обратно и снова рисуется?


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • По вопросам разработки игр стоит заглянуть сюда

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема »


 




[ Время генерации скрипта: 0.1483 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.