AGB  ·  Datenschutz  ·  Impressum  







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

Scanline lahm??

Ein Thema von igel457 · begonnen am 8. Okt 2005 · letzter Beitrag vom 9. Okt 2005
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#1

Scanline lahm??

  Alt 8. Okt 2005, 18:21
Ich habe folgendes Problem:

in meinem Spiel sollen bestimmte Teile der Hintergrundgrafik aufgehellt/abgedunkelt werden.

Ich versuche das so:
(buffer ist ein TBitmap)
Delphi-Quellcode:
  for oy := 0 to buffer.Height-1 do
  begin
    row := buffer.ScanLine[oy];
    for ox := 0 to buffer.Width-1 do
    begin
      gamma := 10;
      if gamma <> 0 then
      begin
        b := cut(row[ox].rgbtBlue+gamma);
        g := cut(row[ox].rgbtGreen+gamma);
        r := cut(row[ox].rgbtRed+gamma);
        row[ox].rgbtBlue := b;
        row[ox].rgbtGreen := g;
        row[ox].rgbtRed := r;
      end;
    end;
  end;
und so:
Delphi-Quellcode:
type
  TRGBTripleArray = array[0..32768] of TRGBTriple;
  // 32768 = maximale Anzahl der Pixel in der Breite eines Bildes (also eine "ScanLine")
  pRGBTripleArray = ^TRGBTripleArray; // Pointer auf TRGBTripleArray
Doch leider ist das furchtbar lahm! Ich brauche für ein 1024x768 großes bild eine halbe Minute! Dabei hatte ich schon öfters ScanLine verwendet, und da war das nicht so lahm.

(Apropos: Das ganze ist mit DelphiX in einem TSprite)

Was mache ich falsch?
Andreas
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#2

Re: Scanline lahm??

  Alt 8. Okt 2005, 18:25
Dein Code ist ziemlich ineffizient Wenn du aufhellen/abdunkeln-Additionen statt so mit MMX oder SSE lösen würdest, dürfte es schon ein gutes Stück schneller werden.
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#3

Re: Scanline lahm??

  Alt 8. Okt 2005, 18:52
Delphi-Quellcode:
procedure MakeDarker(Bitmap: TBitmap; const dp: Byte = 10);
var
  PixelLine: PByteArray;
  x, y: integer;
begin
  if Bitmap.PixelFormat <> pf24Bit then
    Bitmap.PixelFormat := pf24Bit;

  for y := 0 to Bitmap.height - 1 do
  begin
    PixelLine := Bitmap.ScanLine[y];
    for x := 0 to (Bitmap.width * 3) - 1 do
       PixelLine^[x] := PixelLine^[x] - round(PixelLine^[x] / dp);
  end;
end;
Die tut's bei mir recht schnell.
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
Phantom1

Registriert seit: 20. Jun 2003
282 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: Scanline lahm??

  Alt 8. Okt 2005, 18:53
Als erstes würde ich 32bit anstatt 24bit Farbtiefe verwenden, bringt schonmal ein einiges.

Und dann noch ein paar Sachen:
Delphi-Quellcode:
var
  p: PRGBQuad;
...
  Buffer.PixelFormat:=pf32bit;
  p:=Buffer.ScanLine[Buffer.Height-1];
  gamma := 10;

  if gamma <> 0 then
    for x := 0 to buffer.Width*buffer.Height-1 do
    begin
      p^.rgbBlue := cut(p^.rgbBlue+gamma);
      p^.rgbGreen := cut(p^.rgbGreen+gamma);
      p^.rgbRed := cut(p^.rgbRed+gamma);
      Inc(p);
    end;
Jetzt müsste man nur noch wissen was Cut() für eine function ist?

mfg
Phantom1
  Mit Zitat antworten Zitat
Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#5

Re: Scanline lahm??

  Alt 8. Okt 2005, 18:58
Ich verstehe das schon, es wäre wirklich besser Zeile für Zeile abzudunklen, anstatt Pixel für Pixel.

Leider wird nicht das gesammte Bild dunkler, sondern nur an einigen Stellen.

gamma wird erst noch ausgerechnet (hab ich vergessen zu sagen )

@Phantom1
Delphi-Quellcode:
function Cut(AValue:integer):byte;
begin
  result := AValue;
  if AValue > 255 then result := 255;
  if AValue < 0 then result := 0;
end;
Andreas
  Mit Zitat antworten Zitat
Phantom1

Registriert seit: 20. Jun 2003
282 Beiträge
 
Delphi 10.4 Sydney
 
#6

Re: Scanline lahm??

  Alt 8. Okt 2005, 19:22
Die Cut function könntest du auch noch verbessern (wenn auch nur minimal),
zb so hier:
Delphi-Quellcode:
function Cut(AValue: Integer): Byte;
begin
  if AValue > 255 then
    Result := 255
  else
    if AValue < 0 then
      Result := 0
    else
      Result := AValue;
end;
  Mit Zitat antworten Zitat
Benutzerbild von dizzy
dizzy

Registriert seit: 26. Nov 2003
Ort: Lünen
1.932 Beiträge
 
Delphi 7 Enterprise
 
#7

Re: Scanline lahm??

  Alt 9. Okt 2005, 00:49
Die Cut-Funktion könntest du mit MMX sogar komplett weglassen. Hier mal ein ASM-Beispiel (Achtung! Delphi kennt die MMX-Mnemonics meine ich erst ab D7):
Voraussetzung: Farbe in 32Bit
Delphi-Quellcode:
function Darken(Color: LongInt; Value: Byte): LongInt;
// EAX=Color; EDX=Value
asm
        // MMX-Register befüllen
        MOVD MM1, EAX
        PUNPCKLBW MM1, MM0
        MOVD MM2, EDX
        PSHUFW MM2, MM2, 0
        // Wert von Value von allen RGB abziehen, wenn 0 erreicht 0 belassen
        PSUBUSB MM1, MM2
        // Ergebnis zurückschreiben
        PACKUSWB MM1, MM0
        MOVD EAX, MM1
        // FPU zurücksetzen
        EMMS
end;
Wenn du aufhellen möchtest, dann einfach in Zeile 10 statt PSUBUSB PADDUSB verwenden.
Fabian K.
INSERT INTO HandVonFreundin SELECT * FROM Himmel
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#8

Re: Scanline lahm??

  Alt 9. Okt 2005, 00:58
Ab D6 wird schon SSE2 unterstützt, inklusive allem was drunterliegt.. Also SSE, 3DNow!, MMX (klar..)...
  Mit Zitat antworten Zitat
Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#9

Re: Scanline lahm??

  Alt 9. Okt 2005, 09:06
Also das mit Assembler lass ich lieber, damit kenn ich mich nämlich überhaupt ger nicht aus.

Komischerweise funktioniert folgende Funktion ohne Probleme. Die macht natürlich nicht das was ich will, aber diese Funktion geht:

Delphi-Quellcode:
procedure Antialiasing(const DC: TCanvas; const Rectangle: TRect);
var
  cx, cy: Smallint;
  r, g, b: Byte;
  Row1: pRGBTripleArray;
  Row2: pRGBTripleArray;
  Row3: pRGBTripleArray;
  TEMP: TBitmap;
  CurRect: TRect;
begin
  TEMP := TBitmap.Create;
  try
    with TEMP do begin
      Width := Rectangle.Right - Rectangle.Left;
      Height := Rectangle.Bottom - Rectangle.Top;
      CurRect := Rect(0, 0, Width, Height);
      PixelFormat := pf24Bit;
      Canvas.CopyRect(CurRect, DC, Rectangle);
      with Canvas do begin
        for cy := 1 to (Height - 2) do begin
          Row1 := ScanLine[cy - 1];
          Row2 := ScanLine[cy];
          Row3 := ScanLine[cy + 1];

          for cx := 1 to (Width - 2) do begin
            r := (Row1[cx - 1].rgbtRed+Row1[cx].rgbtRed+
            Row1[cx + 1].rgbtRed+
            Row2[cx - 1].rgbtRed+
            Row2[cx + 1].rgbtRed+
            Row2[cx - 1].rgbtRed+
            Row3[cx].rgbtRed+
            Row3[cx + 1].rgbtRed+
            Row3[cx].rgbtRed) div 9;

            g := (Row1[cx - 1].rgbtGreen+
            Row1[cx].rgbtGreen+
            Row1[cx + 1].rgbtGreen+
            Row2[cx - 1].rgbtGreen+
            Row2[cx + 1].rgbtGreen+
            Row2[cx - 1].rgbtGreen+
            Row3[cx].rgbtGreen+
            Row3[cx + 1].rgbtGreen+
            Row3[cx].rgbtGreen) div 9;

            b := (Row1[cx - 1].rgbtBlue+
            Row1[cx].rgbtBlue+
            Row1[cx + 1].rgbtBlue+
            Row2[cx - 1].rgbtBlue+
            Row2[cx + 1].rgbtBlue+
            Row2[cx - 1].rgbtBlue+
            Row3[cx].rgbtBlue+
            Row3[cx + 1].rgbtBlue+
            Row3[cx].rgbtBlue) div 9;
            Row2[cx].rgbtBlue := b;
            Row2[cx].rgbtGreen := g;
            Row2[cx].rgbtRed := r;
          end;
        end;
      end;
      DC.CopyRect(Rectangle, Canvas, CurRect);
    end;
  finally
    TEMP.Free;
  end;
end;
Was wird hier anders gemacht?
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#10

Re: Scanline lahm??

  Alt 9. Okt 2005, 10:42
Zitat:
Leider wird nicht das gesammte Bild dunkler, sondern nur an einigen Stellen.
Wenn du auf meine damit ansprichst, welchen Wert hast du eingesetzt? Werte wie 1..10 sind bei
der Procedure MakeDarker schon ok. und machen keine Probleme. Es ist aber keine genaue
Gammawert berechnung.
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  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 01: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