AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Scanline verwenden

Ein Thema von Tormentor32 · begonnen am 11. Dez 2006 · letzter Beitrag vom 19. Feb 2007
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Tormentor32
Tormentor32

Registriert seit: 27. Okt 2005
Ort: Düsseldorf
369 Beiträge
 
Delphi XE5 Professional
 
#1

Scanline verwenden

  Alt 11. Dez 2006, 10:32
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
Richard Mahr
  Mit Zitat antworten Zitat
Benutzerbild von ste_ett
ste_ett

Registriert seit: 10. Sep 2004
Ort: Dülmen
464 Beiträge
 
Delphi 7 Professional
 
#2

Re: Scanline verwenden

  Alt 11. Dez 2006, 10:51
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!
Stefan
"Geht nicht!" ist keine Fehlerbeschreibung und "Hab ich schon versucht!" keine Antwort!

Hey, it compiles! Ship it!
  Mit Zitat antworten Zitat
Benutzerbild von Tormentor32
Tormentor32

Registriert seit: 27. Okt 2005
Ort: Düsseldorf
369 Beiträge
 
Delphi XE5 Professional
 
#3

Re: Scanline verwenden

  Alt 11. Dez 2006, 11:11
Oh.. Ich hab im Eifer des Gefechts vergessen eine Frage zu formulieren

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]
Richard Mahr
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#4

Re: Scanline verwenden

  Alt 11. Dez 2006, 12:30
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).
  Mit Zitat antworten Zitat
Benutzerbild von Tormentor32
Tormentor32

Registriert seit: 27. Okt 2005
Ort: Düsseldorf
369 Beiträge
 
Delphi XE5 Professional
 
#5

Re: Scanline verwenden

  Alt 11. Dez 2006, 13:34
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...
Richard Mahr
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#6

Re: Scanline verwenden

  Alt 11. Dez 2006, 13:40
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;
  Mit Zitat antworten Zitat
Benutzerbild von Tormentor32
Tormentor32

Registriert seit: 27. Okt 2005
Ort: Düsseldorf
369 Beiträge
 
Delphi XE5 Professional
 
#7

Re: Scanline verwenden

  Alt 11. Dez 2006, 13:53
Zitat:
1. Du übergibst RGB() immernoch die falsche Reihenfolge! Dies hatte ich oben schon angemerkt. Erst rot, grün und dann blau.


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
Richard Mahr
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#8

Re: Scanline verwenden

  Alt 11. Dez 2006, 14:19
Wozu gibt es Bitmap1, wenn du Image.Picture.bitmap nutzt?
  Mit Zitat antworten Zitat
Benutzerbild von Tormentor32
Tormentor32

Registriert seit: 27. Okt 2005
Ort: Düsseldorf
369 Beiträge
 
Delphi XE5 Professional
 
#9

Re: Scanline verwenden

  Alt 11. Dez 2006, 14:36
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...
Richard Mahr
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#10

Re: Scanline verwenden

  Alt 11. Dez 2006, 16:05
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;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:54 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