Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi nur Bereiche neuzeichnen (https://www.delphipraxis.net/79118-nur-bereiche-neuzeichnen.html)

Cöster 16. Okt 2006 17:09


nur Bereiche neuzeichnen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi!

Zur Performanceverbesserung (2D-Spiel/PaintBox), möchte ich nur Bereiche neuzeichnen. In dem Spiel gibt es mehrere Kugeln, die sich über die PaintBox bewegen. Ich möchte also nur die Kugeln neuzeichnen.

Ich zeichne sie auf ein Bitmap (quadratisch, Seitenlänge = Durchmesser der Kugel) im Speicher und kopiere sie dann per BitBlt alle nacheinander auf die PaintBox.

Da das Bitmap im Speicher ein Quadrat, ist, kommt es gelegentlich vor, dass die Ecken des Quadrats eine andere Kugel übermalen (siehe Anhang).

Wie kann ich das verhindern?

Meine Ideen:
1) Gibt es eine Methode wie BitBlt, die stattdessen Kreise kopiert?
2) Direktes Zeichnen auf PaintBox.Canvas, ohne Bitmap im Speicher
3) Sollte das Bitmap im Speicher die Größe der PaintBox haben, dass ich also doch ALLES neuzeichne?


EDIT: Anhang vergessen

Cöster 16. Okt 2006 17:37

Re: nur Bereiche neuzeichnen
 
So, nun ist auch was im Anhang

Zacherl 16. Okt 2006 17:50

Re: nur Bereiche neuzeichnen
 
Beim zeichnen des Hintergrundes könntest du BrushStyle auf bsClear stellen ...

Florian

Cöster 16. Okt 2006 19:53

Re: nur Bereiche neuzeichnen
 
Hm. An welcher Stelle und wovon muss ich denn Brush.Style auf bsClear setzen?

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Bmp: TBitmap;
begin
  // PaintBox1.Canvas.Brush.Style := bsClear;
  Bmp := TBitmap.Create;
  try
    Bmp.SetSize(30, 30);
    with Bmp.Canvas do
    begin
      // Brush.Style := bsClear;
      Pen.Color := clYellow;
      Brush.Color := clYellow;
      Ellipse(0, 0, 30, 30);
      BitBlt(PaintBox1.Canvas.Handle, 0, 0, 30, 30, Handle, 0, 0, SRCCOPY);
      Pen.Color := clRed;
      Brush.Color := clRed;
      Ellipse(0, 0, 30, 30);
      BitBlt(PaintBox1.Canvas.Handle, 20, 20, 30, 30, Handle, 0, 0, SRCCOPY);
    end;
  finally
    Bmp.Free;
  end;
end;

Cicaro 17. Okt 2006 10:43

Re: nur Bereiche neuzeichnen
 
Du verwendest doch ohnehin Classen aus der Unit Graphics.

Dann kannst du auch Bmp.Transparent auf True setzen und mit PaintBox1.Canvas.Draw(x,y,Bmp) die Kugeln zeichnen. Ggf. müsste man auch mal Bmp.TransparentColor auf einen gewünschten Wert setzen.

Cöster 17. Okt 2006 15:16

Re: nur Bereiche neuzeichnen
 
Ah, danke Cicaro!! Draw statt BitBlt :thumb:

Macht es denn dann überhaupt Sinn, BitBlt statt Draw zu verwenden, wenn der letzte Parameter sowieso SRCCOPY ist und das gesamte Bitmap im Speicher und nicht nur Teile davon auf ein Canvas kopiert werden sollen? Das ist ja meistens der Fall, wenn BitBlt benutzt wird. Oder ist BitBlt vielleicht schneller als Draw?

Cöster 17. Okt 2006 17:20

Re: nur Bereiche neuzeichnen
 
Arghh, Draw selbst ist zwar nur minimal langsamer als BitBlt, aber Transparent ist unerträglich. Bei einem 50x50 Bitmap dauert das ganze allein durch Transparent 200 (!!!) mal so lange.

Hat sonst noch jemand ne Idee?

Gandalfus 17. Okt 2006 20:48

Re: nur Bereiche neuzeichnen
 
try finally wegnehmen das ist nur zeitverschwendung.

Matze 17. Okt 2006 21:06

Re: nur Bereiche neuzeichnen
 
Zitat:

Zitat von Gandalfus
try finally wegnehmen das ist nur zeitverschwendung.

:shock: Resorcen-Schutzblöcke sollte man generell verwenden!

Gandalfus 17. Okt 2006 21:41

Re: nur Bereiche neuzeichnen
 
nicht da wo es auf Geschwindigkeit ankommt

Matze 17. Okt 2006 22:03

Re: nur Bereiche neuzeichnen
 
Zitat:

Zitat von Gandalfus
nicht da wo es auf Geschwindigkeit ankommt

Wieso sollte man dann fehleranfälligen Code schreiben? Auch da sollte der Code keine Speicherleaks erzeugen können. Und ob es ohne try-finally deutlich schneller ist, wage ich auch stark zu bezweifeln.

Gandalfus 17. Okt 2006 22:19

Re: nur Bereiche neuzeichnen
 
Das bei dem Code das Bild nicht freiggeben wird ist extrem unwahrscheinlich und rechtfertigt meiner Meinung nach kein try finaly.

Abgesehen davon sollte das Instanzieren des Backpuffers im Konstruktor des Formulars efolgen und nicht in der Methode und der Backpuffer sollte unter private als Feld deklariert werden

Man kann sich transparenz auch selber basteln mit Masken. (siehe google) Ob das Schneller ist oder du einfach die Grenze der GDI erreicht hast müsste man testen. Da du aber keine Bilder zeichnen willst(?) reicht BrushStyle := bsclear.

Du zeichnste doch erst alles auf ein Hintergrundbild und koppierst dann das Hintergrundbild auf die Paintbox oder?

Man kann die Zeichenfläche auch eingrenzen. Ob das was bringt müsste man testen.
Delphi-Quellcode:
Rgn := CreateRectRgn(0,0,width-10,height-10);
SelectClipRgn(fbild.Canvas.Handle,Rgn);
deleteObject(Rgn);

Cöster 18. Okt 2006 14:08

Re: nur Bereiche neuzeichnen
 
Zitat:

Zitat von Gandalfus
Abgesehen davon sollte das Instanzieren des Backpuffers im Konstruktor des Formulars efolgen und nicht in der Methode und der Backpuffer sollte unter private als Feld deklariert werden

Warum?

Zitat:

Zitat von Gandalfus
Da du aber keine Bilder zeichnen willst(?)

Was verstehst du unter "Bildern"? Worauf kann man denn sonst noch zeichnen?

Zitat:

Zitat von Gandalfus
...reicht BrushStyle := bsclear.

eben nicht. Ich hab es zumindest nicht so hingekriegt, dass es was bringt (siehe Code oben). Wenn ihr mir nen Code mit Brush.Style (mit Punkt in der Mitte, oder?) zeigen könntet, wo das funzt, wär ich dankbar.

Zitat:

Zitat von Gandalfus
Du zeichnste doch erst alles auf ein Hintergrundbild und koppierst dann das Hintergrundbild auf die Paintbox oder?

Ne, ich wollte eigentlich nur Bereiche neuzeichnen, nicht das gesamte Bitmap, weil ich hier irgendwo mal gelesen hab, dass das performanter sei. Ich hab im Speicher ein Bitmap von der Größe eines Kreises (aber rechteckig, weil's glaub ich leider nicht anders geht), auf dem ich den Kreis zeichne, bevor ich ihn auf die PaintBox kopiere. Das mach ich so mit allen Kreisen nacheinander. Nur dann kommt es halt zu den Überschneidungen (siehe Anhang Beitrag 1).
Nur bereichsweises Neuzeichnen scheint wohl nur bei rechteckigen Formen auch einen Vorteil zu bringen. Irre ich mich?


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:46 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz