AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Transparente Polygone zeichnen
Thema durchsuchen
Ansicht
Themen-Optionen

Transparente Polygone zeichnen

Ein Thema von Jacks · begonnen am 24. Aug 2016 · letzter Beitrag vom 25. Aug 2016
 
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#6

AW: Transparente Polygone zeichnen

  Alt 24. Aug 2016, 17:58
Hier mal eine alte Routine von mir:

Delphi-Quellcode:
procedure FillPolygonAlpha(Vertices: TVertexList; Dest: TBitmap;
  Color: TColor);
type
  TIntegerArray = array of integer;
var
  x,y: integer;
  i,j: integer;
  PixelPtr: PColor;
  BasePixelPtr: PColor;
  ColorPartR, ColorPartG, ColorPartB, ColorA: Byte;
  Breakpoints: TIntegerArray;

  function GetBreakpoints(Row: integer; XOffset: integer): TIntegerArray;
  var
    Pt1, Pt2: TPoint;
    PtOld, PtNew: TPoint;
    Count: integer;
    i: integer;

    procedure QuickSort(var SortList: TIntegerArray; L, R: Integer);
    var
      I, J: Integer;
      P, T: Integer;
    begin
      repeat
        I := L;
        J := R;
        P := Sortlist[(L + R) div 2];
        repeat
          while SortList[i] < P do
            Inc(I);
          while SortList[j] > P do
            Dec(J);
          if I <= J then
          begin
            T := SortList[I];
            SortList[I] := SortList[J];
            SortList[J] := T;
            Inc(I);
            Dec(J);
          end;
        until I > J;
        if L < J then
          QuickSort(SortList, L, J);
        L := I;
      until I >= R;
    end;

  begin
    PtOld := Vertices.Last;
    Count := 0;
    SetLength(Result, Vertices.Count);
    for i := 0 to Vertices.Count - 1 do
    begin
      PtNew := Vertices[i];
      if PtNew.Y > PtOld.Y then
      begin
        Pt1 := PtOld;
        Pt2 := PtNew;
      end
      else
      begin
        Pt1 := PtNew;
        Pt2 := PtOld;
      end;
      if ((PtNew.Y < Row) = (Row <= PtOld.Y)) and
         ((XOffset-Pt1.X)*(Pt2.Y-Pt1.Y) < (Pt2.X-Pt1.X)*(Row-Pt1.Y)) then
      begin
        Result[Count] := trunc(Pt2.X * (Row-Pt1.y) / (Pt2.Y-Pt1.Y)
                             + Pt1.X * (Pt2.Y-Row) / (Pt2.Y-Pt1.Y));
        inc(Count);
      end;
      PtOld := PtNew;
    end;
    SetLength(Result,Count);
    if length(Result)>=1 then
      Quicksort(Result,0,high(Result));
  end;
begin

  if Vertices.Count < 3 then exit;

  Dest.PixelFormat := pf32Bit;

  ColorA := Color shr 24;
  ColorPartR := Muldiv(GetRValue(Color), ColorA,255);
  ColorPartG := Muldiv(GetGValue(Color), ColorA,255);
  ColorPartB := Muldiv(GetBValue(Color), ColorA,255);
  
  for y := EnsureRange(Vertices.BoundingBox.Top, 0, Dest.Height-1) to
           EnsureRange(Vertices.BoundingBox.Bottom, 0, Dest.Height-1) do
  begin
    BasePixelPtr := Dest.ScanLine[y];
    x := Vertices.BoundingBox.Left;
    BreakPoints := GetBreakpoints(y,x-1);
    i := 0;
    while i <= high(Breakpoints) do
    begin
      PixelPtr := BasePixelPtr;
      inc(PixelPtr, EnsureRange(Breakpoints[i], 0, Dest.Width-1));
      for j := EnsureRange(Breakpoints[i], 0, Dest.Width) to
               EnsureRange(Breakpoints[i+1], 0, Dest.Width-1) do
      begin
        PixelPtr^ :=
          ColorPartR +
          Muldiv(PixelPtr^ and $00FF0000 shr 16,255-ColorA,255) shl 16 or

          ColorPartG +
          Muldiv(PixelPtr^ and $0000FF00 shr 8,255-ColorA,255) shl 8 or

          ColorPartB +
          Muldiv(PixelPtr^ and $000000FF,255-ColorA,255);
        inc(PixelPtr);
      end;
      inc(i,2);
    end;
  end;
end;
Wahrscheinlich nicht das allerschnellste (Polygone rendern ist sowieso eine Wissenschaft für sich), aber tut seinen Job.

TVertexList ist so deklariert:
Delphi-Quellcode:
  TVertexList = class
  public
    property Items[Index: integer]: TPoint read GetItem write SetItem; default;
    { ... }

    property BoundingBox: TRect read FBoundingBox;
  end;
Die Implementierung kann man sich denken. Wenn man keine Klasse dafür verwenden will, kann man die Routine natürlich auch leicht auf array of TPoint oder so anpassen, aber dazu bin ich jetzt zu faul. Man müsste aber nur drei, vier Stellen ändern.
  Mit Zitat antworten Zitat
 

 

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:29 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