Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.05.11;
Скачать: CL | DM;

Вниз

Быстрый tiling   Найти похожие ветки 

 
tesseract ©   (2008-03-28 20:12) [0]

Использую тупо циклы for + draw в buffer.  paint перерисовывает буфер только при изменении размеров control.  В моём случае что-то дофига умножений выходит, как можно ускорить ?  Не горит, но интересно.


 
Игорь Шевченко ©   (2008-03-28 20:20) [1]

а зачем умножать ? tiling, насколько я понимаю, это заполнение шаблоном ?


 
tesseract ©   (2008-03-28 20:25) [2]


>  tiling, насколько я понимаю, это заполнение шаблоном ?


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

ЗЫ: наследник TCustom Panel все работает быстро кроме этого тайлинга при изменении размера формы.


 
Игорь Шевченко ©   (2008-03-28 20:29) [3]

tesseract ©   (28.03.08 20:25) [2]

DoubleBuffered ?

А вообще код давай (с)


 
antonn ©   (2008-03-28 20:30) [4]

а не надо draw, попробуй canvas.copyrect()/bltbtn


 
tesseract ©   (2008-03-28 20:35) [5]


>  canvas.copyrect()


Copyrect медленне Draw кстати. Он Resize  делает.  


> DoubleBuffered ?


Tripple выходит :-)

Там просто через For идёт заполнение backbuffer - сам буффер меняеться только при изменении размера или параметров картинки.


 
antonn ©   (2008-03-28 20:39) [6]


> Copyrect медленне Draw кстати

а попробывать? :) он почти такой же по скорости, как и BitBlt, я на нем игры пишу :) а вот draw, не знаю, что там проиходит внутрях, но тормозит немеряно...


 
antonn ©   (2008-03-28 20:40) [7]

кстати, блитятся картинки одной pixelformat?


 
tesseract ©   (2008-03-28 20:41) [8]


>  вот draw, не знаю, что там проиходит внутрях, но тормозит
> немеряно...


У меня другие результаты. Возможно потому, что не игры. Внутрях он может вызывать преобразование Tgraphic в HBitmap, но как правило так не делает.


 
tesseract ©   (2008-03-28 20:42) [9]


> кстати, блитятся картинки одной pixelformat?


Задача размножить картинку на весь Canvas, с вычислением обрезки по краям.


 
antonn ©   (2008-03-28 20:58) [10]

покажи код, плиз


 
tesseract ©   (2008-03-28 21:02) [11]

Он в разработке. Говорю пока выходит сильно фиговый.



// простая заливка
   ttSimpleTile: begin
                   WidthDiff := (ClRect.Right  -ClRect.Left-xCount*FullImageWidth);
                   HeightDiff:= (ClRect.Bottom -ClRect.Top- yCount*FullImageHeight);

                   tX:=ClRect.Right-WidthDiff;
                   tY:=ClRect.Left-HeightDiff;
                  for cX:= 0 to xCount-1 do
                   begin
                   for cY := 0 to yCount - 1 do
                     begin
                     // основной вывод
                       TileRec:=Rect(cX*FullImageWidth+fTileBorderWidth+ClRect.Left,cY*FullImageHeight+fTileBorderWidth+clRect.Top,0,0);
                         fBackBuffer.Canvas.Draw(TileRec.left,TileRec.top,FPicture.Bitmap);
                       TileRec:=Rect(tx,cY*FullImageHeight+fTileBorderWidth+ClRect.Top,ClRect.Right,cY*FullImageHeight+fTileBorderWidth+ClRect.Top+HeightDiff);
                         fBackBuffer.Canvas.Draw(TileRec.Left,TileRec.Top,FPicture.Bitmap);
                      end;
                      // край по y-ку

                   end;
                     //вывод оконцовки
                  //   TileRec:=Rect(xCount*FullImageWidth+fTileBorderWidth+clRect.Left,yCount*FullImageHeight+fTileBorderWidth+ClRect.Top,WidthDiff+ClREct.Left,HeightDiff+clRect.Top);
                  //   fBackBuffer.Canvas.CopyRect(TileRec,FPicture.Bitmap.Canvas,FbmpRect);
                end;



 
homm ©   (2008-03-28 21:13) [12]

> [9] tesseract ©   (28.03.08 20:42)
> > кстати, блитятся картинки одной pixelformat?
> Задача размножить картинку на весь Canvas, с вычислением
> обрезки по краям.

Ответ не соответствует вопросу.


 
antonn ©   (2008-03-28 21:16) [13]

так, щас будет много корявого кода :)
procedure FillTexturka2canvas( Acanvas:Tcanvas; _Texturka:Tbitmap; _R:Trect; _x,_y:integer);
var i,ii,xtmp,ytmp,ww,hh:integer;
begin
ww:=_Texturka.Width;
hh:=_Texturka.Height;
xtmp:=(_x-(_x div ww)*ww);
ytmp:=(_y-(_y div _Texturka.Height)*_Texturka.Height);
for i:=-1 to ((_R.Right-_R.Left) div ww) do
for ii:=-1 to ((_R.Bottom-_R.top) div hh) do
Acanvas.CopyRect(rect(i*ww+xtmp,ii*hh+ytmp,(i+1)*ww+xtmp,(ii+1)*hh+ytmp), _Texturka.Canvas ,rect(0,0,ww,hh));
end;

procedure FillTexturka2canvas2( Acanvas:Tcanvas; _Texturka:Tbitmap; _R:Trect; _x,_y:integer);
var i,ii,xtmp,ytmp,ww,hh:integer;
begin
ww:=_Texturka.Width;
hh:=_Texturka.Height;
xtmp:=(_x-(_x div ww)*ww);
ytmp:=(_y-(_y div _Texturka.Height)*_Texturka.Height);
for i:=-1 to ((_R.Right-_R.Left) div ww) do
for ii:=-1 to ((_R.Bottom-_R.top) div hh) do
Acanvas.Draw(i*ww+xtmp,ii*hh+ytmp,_Texturka);
end;

procedure FillTexturka2canvas3( Acanvas:Tcanvas; _Texturka:Tbitmap; _R:Trect; _x,_y:integer);
var i,ii,xtmp,ytmp,ww,hh:integer;
begin
ww:=_Texturka.Width;
hh:=_Texturka.Height;
xtmp:=(_x-(_x div ww)*ww);
ytmp:=(_y-(_y div _Texturka.Height)*_Texturka.Height);
for i:=-1 to ((_R.Right-_R.Left) div ww) do
for ii:=-1 to ((_R.Bottom-_R.top) div hh) do
BitBlt(ACanvas.Handle,i*ww+xtmp,ii*hh+ytmp,(i+1)*ww+xtmp,(ii+1)*hh+ytmp,_Texturka.Canvas.Handle,0,0,SRCCOPY);
end;


Тест для трех процедурок, первая canvas.copyrect(), вторая canvas.draw, третья BitBlt(). В тесте на картнку 1600*1200пикселей копировалась битмапка 48*48 в цикле 1000 раз.
FillTexturka2canvas: 5,36519529716766
FillTexturka2canvas2: 5,53980799235657
FillTexturka2canvas3: 5,13526998543111


 
antonn ©   (2008-03-28 21:17) [14]

и кстати, более чем уверен, что это из-за моего коре дуо результаты так мало расходятся, хотелось бы проверить на атлоне, щас напишу тестик :)


 
tesseract ©   (2008-03-28 21:21) [15]


> и кстати, более чем уверен, что это из-за моего коре дуо
> результаты так мало расходятся, хотелось бы проверить на
> атлоне, щас напишу тестик :)


Всегда считал что bitblt видеокартой выполняеться.


 
antonn ©   (2008-03-28 21:25) [16]

вот и проверим...
http://desksoft.ru/index.php?downloads=attachments&id=71 (208Кб, zip)
запустить и написать сюда, мой кора:
canvas.CopyRect: 5,28903645575066
canvas.Draw: 5,5305635213414
BitBlt: 5,10156989226284

хотелось бы увидеть именно атлоны, они в прошлый раз моего теста нехорошо себя показали :)


 
tesseract ©   (2008-03-28 21:31) [17]

гляну завтра - но умножений всё равно перебор. Алгоритм работает даже в потоке, но подмигивает. +/- 10 миллисекунд неколышет.  BackBuffer перерисовываеться только при изменении размера формы или параметров отрисовки - т.е примерно раз в полгода (именно так софт 24/7) :-).


 
tesseract ©   (2008-03-28 21:33) [18]


> вот и проверим...


VgaSafe поставь.  И так потесть. На процессор ведь дрова видюхи влиять не могут ?


 
antonn ©   (2008-03-28 21:37) [19]


> VgaSafe поставь.  И так потесть.

у меня правило - работает - не трожь :) особенно это косается драйверов и администрирования :)


 
tesseract ©   (2008-03-28 21:45) [20]

Твой код от моего, только читаемостью отличаеться. Умножений много + обрезки ещё выводить.

Вообще там просто в рабочий проект требуеться добавить скины к TPanel и TGridPanel. Поэтому и тайлинг - нужно поддёвку к TControlCollection добавлять.


 
antonn ©   (2008-03-28 21:49) [21]

ну открыть у панели канвас, BitBlt"у хватит :)


 
antonn ©   (2008-03-28 21:52) [22]

а может там просто фон перерисовывается и своим морганием вводит в заблуждение? :)


 
tesseract ©   (2008-03-28 21:56) [23]


> а может там просто фон перерисовывается и своим морганием
> вводит в заблуждение? :)


В других режимах не моргает :-)  В коде есть часть Case - он и выбирает часть прорисовки. Код не тормозит, просто хотелось получить наиболее грматоное решение.


 
antonn ©   (2008-03-28 22:04) [24]

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


 
tesseract ©   (2008-03-28 22:06) [25]


>  может из-за этого как то тормозит? или я что то путаю..
> .


F8  разъяснит. Draw вызывает нужную функцию GDI и всё. Почему он у тебя тормозит - сам не понимаю.


 
Игорь Шевченко ©   (2008-03-28 22:08) [26]

Посмотри в JVCL JvBackgrounds.pas


 
tesseract ©   (2008-03-28 22:10) [27]


> Посмотри в JVCL JvBackgrounds.pas


Гляну, только jvcl как то ожирел, аш перебор. Но функцию глянуть не проблема. Спасибо всем.


 
GrayFace ©   (2008-03-29 01:57) [28]

По-моему, не нужны лишние буфферы, лечше битмапку выводить сразу на канвас, если она не сильно маленькая. А если маленькая, заранее объединить в битмапки побольше. Экономия на лишнем выводе буфера и на том, что вне обновившейся области не рисуется. А вместо умножения складывать. Как-то так:
var
 BmpRect: TRect;
begin
  BmpRect:= bmp.Canvas.ClipRect;
  w:= Width;
  h:= Height;
  y:= 0;
  repeat
    x:= 0;
    repeat
      BitBlt(...);
      inc(x, BmpRect.Right);
    until x >= w;

    inc(y, BmpRect.Bottom);
  until y >= h;
end;


 
tesseract ©   (2008-03-29 15:38) [29]


> По-моему, не нужны лишние буфферы,


Буффер необходим. Потому как идёт пересчёт бордюра + бэка. Пересчёт буффера происходит только при изменении размеров контрола, что снижает нагрузку на перерисовку в 10-15 раз. А вообще почитай ветку про DoubleBuffered или сначала пойми , почему мне нужен именно потомок TWinControl, а не TGraphicControl.


>  BmpRect:= bmp.Canvas.ClipRect


Уже ошибка. См VCL.


 
GrayFace ©   (2008-03-29 22:15) [30]

tesseract ©   (29.03.08 15:38) [29]
Буффер необходим. Потому как идёт пересчёт бордюра + бэка. Пересчёт буффера происходит только при изменении размеров контрола, что снижает нагрузку на перерисовку в 10-15 раз.

Ну тогда его лучше сделать содержащим целое размножающихся картинок.

tesseract ©   (29.03.08 15:38) [29]
А вообще почитай ветку про DoubleBuffered или сначала пойми , почему мне нужен именно потомок TWinControl, а не TGraphicControl.

Забавно выходит, когда ламеры говорят в стиле Юрия Шевченко.
Не знаю, почему тебе нужен TWinControl какиб боком это относится к тому, что я писал, но раз у так, то CS_VREDRAW и CS_HREDRAW не забываешь убрать?

tesseract ©   (29.03.08 15:38) [29]
Уже ошибка. См VCL.

Вряд ли. Что смотреть? (хотя BmpRect вообще не нужен, это я для CopyRect хотел написать пример)


 
tesseract ©   (2008-03-30 17:14) [31]


> Вряд ли. Что смотреть? (хотя BmpRect вообще не нужен, это
> я для CopyRect хотел написать пример)


Нет, тут ты как раз прав. Сам его использую, только он ClientRect после отрисовки border-а. в VCL и WinAPI есть функции как раз для работы с определением координат отрисовки.


> Ну тогда его лучше сделать содержащим целое размножающихся
> картинок.


Буфер перериcовываеться, только если размеры контрола  поменяли. При перерисовке моргает зараза, при перемещениии окна всё ок.


> то CS_VREDRAW


Он не влияет на скорость, так как отсекаю в paint.


 
GrayFace ©   (2008-03-31 00:51) [32]

Хотел сказать: "Ну тогда его лучше сделать содержащим целое число размножающихся картинок." Чтобы его каждый раз не дергать.
А моргает только при расширении и только та область, на которую он увеличился?

tesseract ©   (30.03.08 17:14) [31]
Он не влияет на скорость, так как отсекаю в paint.

Как? В WM_PAINT уже ничего не сделать, моргание происходит из-за приходящего WM_ERASEBKGND - разве что в нем как-то Validate"ить старую область. Не представляю.


 
Slym ©   (2008-03-31 04:28) [33]

GrayFace ©   (29.03.08 1:57) [28]
+1 хоть и tesseract ©   (29.03.08 15:38) [29] Уже ошибка. См VCL.

Зачем умножать когда можно складывать? inc(x, BmpRect.Right);


 
Slym ©   (2008-03-31 05:21) [34]

procedure TileBitmap(Canvas:TCanvas;Img:TBitmap);
var
 ImgWidth,ImgHeight,x,y:integer;
 ClipRect:TRect;
begin
 ImgWidth:=Img.Width;
 ImgHeight:=Img.Height;
 ClipRect:=Canvas.ClipRect;
 y:=ClipRect.Top;
 while y<ClipRect.Bottom do
 begin
   x:=ClipRect.Left;
   while x<ClipRect.Right do
   begin
     Canvas.Draw(x,y,Img);
     inc(x,ImgHeight);
   end;
   inc(y,ImgHeight);
 end;
end;

procedure TileRectBitmap(Canvas:TCanvas;Rect:TRect;Img:TBitmap);
var MyRgn:HRGN;
begin
 MyRgn := CreateRectRgn(Rect.Left,Rect.Top,Rect.Right,Rect.Bottom);
 try
   SelectClipRgn(Canvas.Handle,MyRgn);
   TileBitmap(Canvas,Img);
 finally
   SelectClipRgn(Canvas.Handle,0);
   DeleteObject(MyRgn);
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Bitmap:TBitmap;
 R:TRect;
 i,c:dword;
begin
 Bitmap:=TBitmap.Create;
 try
   ImageList1.GetBitmap(0,Bitmap);
   R:=Rect(200,100,300,200);
   c:=GetTickCount;
   for i:=0 to 1000 do
     TileRectBitmap(Canvas,R,Bitmap);
   Caption:=IntToStr(GetTickCount-c)+"мс/1000ит";
 finally
   Bitmap.Free;
 end;
end;


 
Slym ©   (2008-03-31 05:44) [35]

замена Canvas.Draw(x,y,Img); на BitBlt(Canvas.Handle,X,Y,ImgWidth,ImgHeight,ImgCanvas,0,0,SRCCOPY);
дает незначительные 10% скорости


 
Slym ©   (2008-03-31 06:26) [36]

тесты:
CeleronM430 1.73MHz
Dest 1600*1200 Source 48*48  1000раз
BitBlt: 8,046секов


 
tesseract ©   (2008-03-31 10:05) [37]


> Зачем умножать когда можно складывать? inc(x, BmpRect.Right);


Ну так примерно в итоге и сделано.



Страницы: 1 вся ветка

Текущий архив: 2008.05.11;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.013 c
2-1207738265
Fr1K
2008-04-09 14:51
2008.05.11
Событие по нажатию


15-1206543503
ajlekceu
2008-03-26 17:58
2008.05.11
Путь экспорта файлов из Corel Draw


2-1207833052
Снежинка
2008-04-10 17:10
2008.05.11
Запрос


15-1206691067
Миша
2008-03-28 10:57
2008.05.11
Помогите разобраться с Html


2-1207850349
vodvorezlaya
2008-04-10 21:59
2008.05.11
Смена атрибутов только чтение у папки