![]() |
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:43 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