![]() |
Scanline verwenden
Hallo Leute!
Ich habe in meinem Spiel folgenden Algorythmus:
Delphi-Quellcode:
Ich habe sozusagen mehrere Layer auf die jeweils gezeichnet wird und dann werden die Layer hintereinander gesetzt, so kann ich mit meiner Spielfigur rumlaufen und zum Beispiel teilweise verdeckt sein, wenn ein Gebäude im Weg ist.
for x := 0 to Layer2.Width-1 do
for y := 0 to Layer2.Height-1 do begin if Layer2.Canvas.Pixels[x,y] <> FTransparentcolor then Img.Canvas.Pixels[x,y] := Layer2.Canvas.Pixels[x,y] // überall, wo // Nich Die Transparente Farbe ist, wird im Image drübergezeichnet // layer2: TBitmap; end; Das Problem ist allerdings, das die Prozedur recht häufig benutzt wird, und ich gerne scanline für eine bessere Performance benutzen würde. Ich habe schon hier die Suche benutzt, aber irgendwie komm ich nicht drauf, wie ich scanline in diesem Fall benutzen muss. Danke schonmal für die Hilfe Richard |
Re: Scanline verwenden
Was genau ist jetzt deine Frage?
Willst du wissen, wie du Scanline benutzt? Dazu gibt es jede Menge Einträge, die du ganz einfach über die Suche findest! :) |
Re: Scanline verwenden
Oh.. Ich hab im Eifer des Gefechts vergessen eine Frage zu formulieren :oops:
Wäre das hier ein Lösung?
Delphi-Quellcode:
[edit]Ich taste mich langsam ran[/edit]
var P,P2: PRGBTriple;
begin for y := 0 to Layer2.Height-1 do begin P := Layer2.Scanline[y]; P2 := Img.Picture.Bitmap.ScanLine[y]; for x := 0 to Layer2.Width-1 do if RGB(P^.rgbtBlue,P^.rgbtGreen,P^.rgbtRed) <> FTransparentcolor then begin P2^[x] := P^[x] end; end; end; |
Re: Scanline verwenden
Nein, denn RGB will bestimmt Rot, Grün, Blau haben und nicht Blau, Grün, Rot, wenn ich mich recht entsinne. Auch würdest du ein Problem haben, wenn die Farbe z.B. clWindow oder eine andere Farbkonstante wäre. Daher ColorToRGB() um die Transparenzfarbe nehmen im Vergleich.
Auch musst du beachten, dass dein Code nur funktioniert, wenn beide Bitmaps ein PixelFormat von pf24bit haben. Zur reinen Geschwindigkeit wäre ein Pixelformat von pf32bit schneller (dann PRGBQuad anstatt PRGBTriple nutzen). |
Re: Scanline verwenden
Also ich habe jetzt das gemacht:
Delphi-Quellcode:
aber jetzt sagt er, dass ein Array-Typ erforderlich ist.
for y := 0 to Layer2.Height-1 do
begin P := Layer2.Scanline[y]; P2 := img.Picture.Bitmap.ScanLine[y]; for x := 0 to Layer2.Width-1 do if RGB(P^.rgbBlue,P^.rgbGreen,P^.rgbRed) <> ColorToRGB(clFuchsia) then begin P2^[x] := P^[x] inc(P2); inc(P); end; end; Daraufhin habe ich folgendes gemacht:
Delphi-Quellcode:
aber das funzt auch nicht... :cry:
for y := 0 to Layer2.Height-1 do
begin P := Layer2.Scanline[y]; P2 := img.Picture.Bitmap.ScanLine[y]; for x := 0 to Layer2.Width-1 do if RGB(P^.rgbBlue,P^.rgbGreen,P^.rgbRed) <> ColorToRGB(clFuchsia) then begin P2^.rgbBlue := P^.rgbBlue; P2^.rgbGreen := P^.rgbGreen; P2^.rgbRed := P^.rgbRed; P2^.rgbReserved := P^.rgbReserved inc(P2); inc(P); end; end; |
Re: Scanline verwenden
1. Du übergibst RGB() immernoch die falsche Reihenfolge! Dies hatte ich oben schon angemerkt. Erst rot, grün und dann blau.
2. PRGBTriple ist ein Zeiger auf einen Zeiger und kein Array Typ. Du kannst den Pointer mit Inc() einfach inkrementieren um auf den nächsten Pixel zu zu greifen. Es ist kein Array - aber das hat dir der Compiler schon gesagt. 3. Wenn du die Zeiger inkrementierst, dann solltest du dies immer machen und nicht nur wenn die If Bedingung hinhaut, sonst würdest du ständig auf der Stelle trampeln.
Delphi-Quellcode:
for y := 0 to Layer2.Height-1 do
begin P := Layer2.Scanline[y]; P2 := img.Picture.Bitmap.ScanLine[y]; for x := 0 to Layer2.Width-1 do Begin if RGB(P^.rgbRed, P^.rgbGreen, P^.rgbBlue) <> ColorToRGB(clFuchsia) then P2^ := P^; Inc(P2); Inc(P); End; end; |
Re: Scanline verwenden
Zitat:
Ich habe deinen Code umgesetzt, aber es tut sich imer noch nichts, die Bedingung funktioniert aber, ich habe das mit einem Showmessage überprüft. Hier mal den Ganzen Code ausm Kontext:
Delphi-Quellcode:
Das sollte klappen, tuts aber nicht :pale:
procedure TForm1.FormCreate(Sender: TObject);
var x,y: integer; P,P2: PRGBQuad; //P,P2: PRGBTriple; begin Bitmap1 := TBitmap.Create; Bitmap2 := TBitmap.Create; Bitmap1.LoadFromFile('i.bmp'); Bitmap2.LoadFromFile('X.bmp'); Bitmap1.PixelFormat:= pf32Bit; Bitmap2.PixelFormat:= pf32Bit; image1.Canvas.Draw(0,0,bitmap1); for y := 0 to bitmap2.Height-1 do begin P := bitmap2.Scanline[y]; P2 := image1.Picture.Bitmap.ScanLine[y]; for x := 0 to bitmap2.Width-1 do begin if RGB(P^.rgbRed, P^.rgbGreen, P^.rgbBlue) <> ColorToRGB(clFuchsia) then P2^ := P^; inc(P); inc(P2); end; end; end; |
Re: Scanline verwenden
Wozu gibt es Bitmap1, wenn du Image.Picture.bitmap nutzt?
|
Re: Scanline verwenden
ich will das hinterher halt so machen, dass ich hinterher meine eigene Komponente habe, wo ich dann
Delphi-Quellcode:
drin habe, mit denen ich dann nacheinander die Zeichenprozedur aufrufe (s.o.) deswegen habe ich das über die zwei BitMaps gemacht.
FLayer: array of TBitmap
//(...) procedure Paint; begin for i := low(FLayers) to high(FLayers) PaintLayer(i) end; Ich habe halt die Farbe clFuchsia als Transparente Frabe genommen und habe zwei Bilder gemalt (X.bmp und i.bmp), die jeweils in die Beiden Bitmaps gemalt werden und dann Nacheinander auf das Image (halt so, dass überall wo clFuchsia ist einfach nichts gezeichnet wird) geklatscht werden. Aber das Ding funktioniert noch nicht, wie gesagt, er malt den Grundlayer per "Draw" und dann sollen die anderen Layer drübergelegt werden, aber er zeichnet nur den Grundlayer... :?: :?: :?: edit: Ja ich sollte nicht so schnell schreiben... |
Re: Scanline verwenden
Verstehe ich das richtig, dass du nur folgendes erreichen willst? Du malst auf einen Canvas nacheinander zwei unterschiedliche Bilder. Bei beiden Bildern sollen die mit clFuchsia gefärbten Bereiche auf dem Zielcanvas nicht verändert werden?
Wenn ich richtig liege, dann folgendes:
Delphi-Quellcode:
Begin
Bitmap1 := TBitmap.Create; Bitmap2 := TBitmap.Create; Try Bitmap1.LoadFromFile('whatever1.bmp'); Bitmap2.LoadFromFile('whatever2.bmp'); Bitmap1.TransparentColor := clFuchsia; Bitmap2.TransparentColor := clFuchsia; Bitmap1.TransparentMode := tmFixed; Bitmap2.TransparentMode := tmFixed; Bitmap1.Transparent := True; Bitmap2.Transparent := True; DeinZielCanvas.Draw(0, 0, Bitmap1); DeinZielCanvas.Draw(0, 0, Bitmap2); Finally Bitmap1.Free; Bitmap2.Free; End; End; |
Re: Scanline verwenden
Ja genau das ist es! :hello:
Danke! Das hatte ich vorher schon, nur dass ich bei den Bitmaps nicht den TransparentMode gesetzt hatte... :wall: Naja vielen Dank! |
Re: Scanline verwenden
--------
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:24 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