-
Использую тупо циклы for + draw в buffer. paint перерисовывает буфер только при изменении размеров control. В моём случае что-то дофига умножений выходит, как можно ускорить ? Не горит, но интересно.
-
а зачем умножать ? tiling, насколько я понимаю, это заполнение шаблоном ?
-
> tiling, насколько я понимаю, это заполнение шаблоном ?
ага заполнение изображения нужным количеством копий по размеру отображения, нужно перерисовка в runtime и быстрая.
ЗЫ: наследник TCustom Panel все работает быстро кроме этого тайлинга при изменении размера формы.
-
tesseract © (28.03.08 20:25) [2]
DoubleBuffered ?
А вообще код давай (с)
-
а не надо draw, попробуй canvas.copyrect()/bltbtn
-
> canvas.copyrect()
Copyrect медленне Draw кстати. Он Resize делает.
> DoubleBuffered ?
Tripple выходит :-)
Там просто через For идёт заполнение backbuffer - сам буффер меняеться только при изменении размера или параметров картинки.
-
> Copyrect медленне Draw кстати
а попробывать? :) он почти такой же по скорости, как и BitBlt, я на нем игры пишу :) а вот draw, не знаю, что там проиходит внутрях, но тормозит немеряно...
-
кстати, блитятся картинки одной pixelformat?
-
> вот draw, не знаю, что там проиходит внутрях, но тормозит > немеряно...
У меня другие результаты. Возможно потому, что не игры. Внутрях он может вызывать преобразование Tgraphic в HBitmap, но как правило так не делает.
-
> кстати, блитятся картинки одной pixelformat?
Задача размножить картинку на весь Canvas, с вычислением обрезки по краям.
-
покажи код, плиз
-
Он в разработке. Говорю пока выходит сильно фиговый.
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;
end;
end;
-
> [9] tesseract © (28.03.08 20:42) > > кстати, блитятся картинки одной pixelformat? > Задача размножить картинку на весь Canvas, с вычислением > обрезки по краям.
Ответ не соответствует вопросу.
-
так, щас будет много корявого кода :) 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
-
и кстати, более чем уверен, что это из-за моего коре дуо результаты так мало расходятся, хотелось бы проверить на атлоне, щас напишу тестик :)
-
> и кстати, более чем уверен, что это из-за моего коре дуо > результаты так мало расходятся, хотелось бы проверить на > атлоне, щас напишу тестик :)
Всегда считал что bitblt видеокартой выполняеться.
-
вот и проверим... http://desksoft.ru/index.php?downloads=attachments&id=71 (208Кб, zip) запустить и написать сюда, мой кора: canvas.CopyRect: 5,28903645575066 canvas.Draw: 5,5305635213414 BitBlt: 5,10156989226284 хотелось бы увидеть именно атлоны, они в прошлый раз моего теста нехорошо себя показали :)
-
гляну завтра - но умножений всё равно перебор. Алгоритм работает даже в потоке, но подмигивает. +/- 10 миллисекунд неколышет. BackBuffer перерисовываеться только при изменении размера формы или параметров отрисовки - т.е примерно раз в полгода (именно так софт 24/7) :-).
-
> вот и проверим...
VgaSafe поставь. И так потесть. На процессор ведь дрова видюхи влиять не могут ?
-
> VgaSafe поставь. И так потесть.
у меня правило - работает - не трожь :) особенно это косается драйверов и администрирования :)
-
Твой код от моего, только читаемостью отличаеться. Умножений много + обрезки ещё выводить.
Вообще там просто в рабочий проект требуеться добавить скины к TPanel и TGridPanel. Поэтому и тайлинг - нужно поддёвку к TControlCollection добавлять.
-
ну открыть у панели канвас, BitBlt'у хватит :)
-
а может там просто фон перерисовывается и своим морганием вводит в заблуждение? :)
-
> а может там просто фон перерисовывается и своим морганием > вводит в заблуждение? :)
В других режимах не моргает :-) В коде есть часть Case - он и выбирает часть прорисовки. Код не тормозит, просто хотелось получить наиболее грматоное решение.
-
а draw вроде бы умеет копировать с учетом прозрачного ключа, может из-за этого как то тормозит? или я что то путаю...
-
> может из-за этого как то тормозит? или я что то путаю.. > .
F8 разъяснит. Draw вызывает нужную функцию GDI и всё. Почему он у тебя тормозит - сам не понимаю.
-
Посмотри в JVCL JvBackgrounds.pas
-
> Посмотри в JVCL JvBackgrounds.pas
Гляну, только jvcl как то ожирел, аш перебор. Но функцию глянуть не проблема. Спасибо всем.
-
По-моему, не нужны лишние буфферы, лечше битмапку выводить сразу на канвас, если она не сильно маленькая. А если маленькая, заранее объединить в битмапки побольше. Экономия на лишнем выводе буфера и на том, что вне обновившейся области не рисуется. А вместо умножения складывать. Как-то так: 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;
-
> По-моему, не нужны лишние буфферы,
Буффер необходим. Потому как идёт пересчёт бордюра + бэка. Пересчёт буффера происходит только при изменении размеров контрола, что снижает нагрузку на перерисовку в 10-15 раз. А вообще почитай ветку про DoubleBuffered или сначала пойми , почему мне нужен именно потомок TWinControl, а не TGraphicControl.
> BmpRect:= bmp.Canvas.ClipRect
Уже ошибка. См VCL.
-
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 хотел написать пример)
-
> Вряд ли. Что смотреть? (хотя BmpRect вообще не нужен, это > я для CopyRect хотел написать пример)
Нет, тут ты как раз прав. Сам его использую, только он ClientRect после отрисовки border-а. в VCL и WinAPI есть функции как раз для работы с определением координат отрисовки.
> Ну тогда его лучше сделать содержащим целое размножающихся > картинок.
Буфер перериcовываеться, только если размеры контрола поменяли. При перерисовке моргает зараза, при перемещениии окна всё ок.
> то CS_VREDRAW
Он не влияет на скорость, так как отсекаю в paint.
-
Хотел сказать: "Ну тогда его лучше сделать содержащим целое число размножающихся картинок." Чтобы его каждый раз не дергать. А моргает только при расширении и только та область, на которую он увеличился?
tesseract © (30.03.08 17:14) [31] Он не влияет на скорость, так как отсекаю в paint. Как? В WM_PAINT уже ничего не сделать, моргание происходит из-за приходящего WM_ERASEBKGND - разве что в нем как-то Validate'ить старую область. Не представляю.
-
GrayFace © (29.03.08 1:57) [28]+1 хоть и tesseract © (29.03.08 15:38) [29] Уже ошибка. См VCL.Зачем умножать когда можно складывать? inc(x, BmpRect.Right);
-
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;
-
замена Canvas.Draw(x,y,Img); на BitBlt(Canvas.Handle,X,Y,ImgWidth,ImgHeight,ImgCanvas,0,0,SRCCOPY); дает незначительные 10% скорости
-
тесты: CeleronM430 1.73MHz Dest 1600*1200 Source 48*48 1000раз BitBlt: 8,046секов
-
> Зачем умножать когда можно складывать? inc(x, BmpRect.Right);
Ну так примерно в итоге и сделано.
|