Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Scanline verwenden (https://www.delphipraxis.net/82319-scanline-verwenden.html)

Tormentor32 11. Dez 2006 10:32


Scanline verwenden
 
Hallo Leute!

Ich habe in meinem Spiel folgenden Algorythmus:

Delphi-Quellcode:
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;
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.

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

ste_ett 11. Dez 2006 10:51

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! :)

Tormentor32 11. Dez 2006 11:11

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:
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;
[edit]Ich taste mich langsam ran[/edit]

Muetze1 11. Dez 2006 12:30

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).

Tormentor32 11. Dez 2006 13:34

Re: Scanline verwenden
 
Also ich habe jetzt das gemacht:

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
      if RGB(P^.rgbBlue,P^.rgbGreen,P^.rgbRed) <> ColorToRGB(clFuchsia)
        then
          begin
            P2^[x] := P^[x]
            inc(P2);
            inc(P);
          end;
  end;
aber jetzt sagt er, dass ein Array-Typ erforderlich ist.
Daraufhin habe ich folgendes gemacht:

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
      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;
aber das funzt auch nicht... :cry:

Muetze1 11. Dez 2006 13:40

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;

Tormentor32 11. Dez 2006 13:53

Re: Scanline verwenden
 
Zitat:

1. Du übergibst RGB() immernoch die falsche Reihenfolge! Dies hatte ich oben schon angemerkt. Erst rot, grün und dann blau.
:wall:

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:
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;
Das sollte klappen, tuts aber nicht :pale:

Muetze1 11. Dez 2006 14:19

Re: Scanline verwenden
 
Wozu gibt es Bitmap1, wenn du Image.Picture.bitmap nutzt?

Tormentor32 11. Dez 2006 14:36

Re: Scanline verwenden
 
ich will das hinterher halt so machen, dass ich hinterher meine eigene Komponente habe, wo ich dann

Delphi-Quellcode:
FLayer: array of TBitmap
//(...)
procedure Paint;
begin
  for i := low(FLayers) to high(FLayers)
    PaintLayer(i)
end;
drin habe, mit denen ich dann nacheinander die Zeichenprozedur aufrufe (s.o.) deswegen habe ich das über die zwei BitMaps gemacht.

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...

Muetze1 11. Dez 2006 16:05

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;


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:21 Uhr.
Seite 1 von 2  1 2      

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