![]() |
schwarze Pixel weg : copyMode cmSrcAND cmSrcPaint zu langsam
hallo !
altbekanntes Problem : ich will eine Bitmap (60*100 Pixel) "Org-Image" ohne eine bestimmte Farbe zB schwarz in eine anderes Bild, sagen wir "ZielImage" , einfügen zB grüner Hase auf schwarzem Hintergrund : nur der grüne Hase soll gezeichnet werden. Bei mir soll dies allerdings mind. alle 10 msec geschehen, und das verursacht bei meinem 1,3 GHZ Celeron eine Auslastung von über 80% , wenn ich es mit einem der folgenden Wege probiere : - ZielImage.copyRect(..Org-Image,orgRect) : zuerst ein MaskImage (da wo beim Org.-Image schwarz ist , ist weiss, und wo bei Org-Image nicht schwarz ist , ist schwarz.) mit dem copyMode cmSrcAnd des ZielImage in dieses kopieren und dann mit cmSrcPaint (OR-Verknüpfung) das Org-Image drüberkopieren. - mit 2 for-schleifen durch das Org-Image- laufen und mit der Abfrage if NOT Org-Image.Canvas.Pixel[x,y] = clBlack nur die Pixel im ZielImage einfärben die nicht clBlack sind. - mit Canvas.BrushCopy (es wird eine Farbe angegeben die nicht gezeichnet werden soll) Ein Zugriff auf Pixel in einem Image.Canvas Objekt sind anscheinend recht teuer. (obwohl des ZielImage gar nicht sichtbar ist (es ist eine Art Buffer) ) Warum eigentlich ist es nicht wie ein array [60][100] of TColor ? Damit gäbe es keine Geschwindigkeits-Probleme. Hat jemand noch eine andere Idee wie man dieses Problem lösen könnte ? gruß henrik |
Re: schwarze Pixel weg : copyMode cmSrcAND cmSrcPaint zu lan
Am komfortabelsten lässt sich sowas mit der
![]() Gruss, Fabian |
Re: schwarze Pixel weg : copyMode cmSrcAND cmSrcPaint zu lan
hey,
danke, damit klappt es besser. die pixel-manipulationen kosten hier fast nichts, dafür aber das TPaintbox32.refresh (was explizit aufgerufen werden muss) alleine 30% der cpu, was zwar 2-3 mal so schnell ist wie mit dem langsamen Canvas , aber da müsste sich doch noch was machen lassen, denn mit Canvas kostet wiederum das einfache refresh (was explizit gar nicht aufgerufen werden muss) nach einem paintbox.cancas.copyrect(...) fast nichts ! |
Re: schwarze Pixel weg : copyMode cmSrcAND cmSrcPaint zu lan
Evtl. ist TPaintBox32.Flush da schneller. Laut Hilfe zur G32 müsste es das auch tun :)
|
Re: schwarze Pixel weg : copyMode cmSrcAND cmSrcPaint zu lan
Moin Henrik,
wozu muss das Bild 100 mal pro Sekunde neu gezeichnet werden? :gruebel: |
Re: schwarze Pixel weg : copyMode cmSrcAND cmSrcPaint zu lan
hi Christian,
100 mal pro sekunde weil es im Rahmen eines Spiels welches ich dabei bin zu entwickeln, diese hohe frequnez braucht um flüssig zu wirken : es soll in der paintbox ein bereich aus einer Map dargestellt werden (scrolling), und dabei der Pixel-verschiebe-Wert von einem Ausschnitt zum nächsten möglichst klein gehalten werden, sonst wirkt es zu ruckelig, deshalb muss aber die BildAuschnittswiederholungsrate hochgesetzt werden ! |
Re: schwarze Pixel weg : copyMode cmSrcAND cmSrcPaint zu lan
hi dizzy,
mit Flush gehts leider auch nicht schneller. Die PaintBox32 ist 400*400 Pixel groß. In der ontimer Methode mit der einzigen Anweisung PaintBox321.Flush; wird die cpu mit 70% belastet (obwohl nur die leere Paintbox gezeichnet wird) |
Re: schwarze Pixel weg : copyMode cmSrcAND cmSrcPaint zu lan
Also ich selber habe ja immer ein TImage32 genommen, in das TImage32.Bitmap gezeichnet, und dann TImage32.Changed aufgerufen. Bisher kam mir das recht flüssig vor :).
Letzten Endes bleibt noch der Weg über DirectX. Das ist noch viel performanter, aber leider auch ungleich komplexer. |
Re: schwarze Pixel weg : copyMode cmSrcAND cmSrcPaint zu lan
also wenn ich folgendes mache :
Delphi-Quellcode:
procedure TForm1.MMTimer1Timer(Sender: TObject; Time: Cardinal);
begin buffer32.Changed; end; mit einem TimerInterval von 10 msec und buffer32 ist ein (leeres) TImage32 auf Form1 und ist 400*400 groß, dann ist die cpu auslastung 50 % bei 1.3GHZ. :cry: |
Re: schwarze Pixel weg : copyMode cmSrcAND cmSrcPaint zu lan
Ein Timer ist im übrigen sehr sehr unschön, zumal du an 10msec Intervalldauer real so gut wie nie heran kommen dürftest. Ein MMTimer (Unit MMSystem) ist da deutlich besser geeignet, oder ein Gameloop, oder Application.OnIdle. (Gameloop ist eigentlich das Übliche.) Und damit die Spielgeschwindigkeit nicht von der Geschwindigkeit des Rechners abhängt, solltest du auf jeden Fall ein Framerate-Control einbauen. (Mal im Forum stöbern, dazu hatten wir schon mal was meine ich.)
Damit die CPU-Auslastung nicht so irre hoch wird, könnte man zu dem ein Framerate-Limit einbauen. Das Zeichnen selber wirst du aber vermutlich auf konventionellem Wegen (GDI) nicht viel schneller bekommen. Genau deshalb gibt es ja DirectX ;). Da musst du dann abwägen wie sehr sich der evtl. Mehraufwand lohnt. Grundsätzlich ist hohe CPU-Auslastung bei Games völlig normal und auch okay. Nur sollte nicht grad 80% auf das pure Neuzeichnen entfallen, da hast du Recht :stupid: :D. |
Re: schwarze Pixel weg : copyMode cmSrcAND cmSrcPaint zu lan
hey dizzy,
ich verwende doch den MMTimer ! (ich weiss : der TTimer ist sehr ungenau ) Das Dilemma ist im Augenblick : -mit G32 kann man superschnelle Pixelmanipulationen machen, dafür klappts mit dem Anzeigen des bearbeiteten Bildes nur schlecht (bei mir zumindest). -mit der normalen TPaintbox und copyrects... kostest das Anzeigen nichts !!,siehe code, (selbst bei 3 msec nur ca. 2% Auslastung) , dafür bremsen Pixelmanipulationen das ganze wieder auf 70 %. Das folgende mit den ganzen copyRects-hin und hergeschiebe kostet fast nix bei timerInterval von 3 msec (!!!!) : Nur fehlen leider die Pixelmanipulationen :
Delphi-Quellcode:
procedure TForm1.viewTimerTimer(Sender: TObject; Time: Cardinal);
var tr : TRect; begin tr.Left:=10; tr.Top:=frameNr; tr.Right:=10+viewRect.Right; tr.Bottom:=frameNr+viewRect.Bottom; buffer.Canvas.CopyMode:=cmSrcCopy; buffer.Canvas.CopyRect(viewRect,orgImage.Canvas,tr); buffer.Canvas.CopyRect(stdCarPos,carMask.Canvas,carRect); buffer.Canvas.CopyRect(stdCarPos,car.Canvas,carRect); PaintBox1.Canvas.CopyMode:=cmSrcCopy; PaintBox1.Canvas.CopyRect(viewRect,Buffer.Canvas,viewRect); dec(frameNr,shiftAdd); if frameNr<10 then frameNr:=OrgImage.Height-700; end; Man müsste beides kombinieren können. Mit G32 manipulieren und mit dem anderen das Ergebnis anzeigen. Ein TImage32 in ein TImage umwandeln ? |
Re: schwarze Pixel weg : copyMode cmSrcAND cmSrcPaint zu lan
Nun, du kannst ein TBitmap32 auf ein beliebigen Canvas zeichnen. "TBitmap32.DrawTo(TCanvas.Handle, X, Y);"
Damit lässt sich also auch eine normale PaintBox vollkleistern :). Ob das nun aber schneller weiss ich nicht - einen Versuch wäre es wohl wert. (Im Hintergrund arbeitet da meine ich dann ein "BitBlt".) Das mit dem Timer: Oki, bin von nem normalen Timer ausgegangen :drunken: Gruss, Fabian \\edit: Korrektur: Die Methode nutzt "StretchDIBits", welches ein API-Call ist. |
Re: schwarze Pixel weg : copyMode cmSrcAND cmSrcPaint zu lan
das ist es ! :hello: danke dizzy
es funktioniert : mit 3 msec Interval nur ca. 4 % auslastung, und das mit einigen copyRects, drawTo's und pixel-manipulationen mit G32. grüsse henrik |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz