Delphi - Smooth Shading színátmenet sokszögre

GDI újdonságai 2. rész

forráskód letöltése
Ezen a héten egy olyan komponenst készítünk, mellyel egy tetszőleges számú sokszöget rajzolhatunk ki, megadva a sokszög egyes koordinátáit és azt, hogy milyen színű legyen az adott pont. A pontok közötti színátmenetet a komponensben használt függvény automatikusan elkészíti, felhasználva a Smooth Shading technikát, melynek révén a színátmenet kirajzolása tökéletesen egyenletes árnyékoltságú lesz. A mellékelt példaprogram megnyitása előtt a TriangleGradient.pas-ban lévő komponenst telepítenie kell a Delphi alá.

A komponens használatához két tömb típusú property-t kell a megfelelő értékekkel feltölteni. Ebből a Triangles nevű az egyik, melynek minden egyes eleme egy-egy TTriangleItem objektumot tárol. Nézzük milyen tulajdonságai vannak ennek az osztálynak.
Az X és Y property-kbe adhatjuk meg az adott pont koordinátáit. A Color fogja tárolni e pont színét. Ha az AutoWidth property-t igazra állítjuk, akkor az X koordináta értéke automatikusan változik a komponens Width property-ének változásakor. Ha az AutoHeight property-t igazra állítjuk, akkor az Y koordináta értéke automatikusan változik a komponens Height property-ének változásakor.

A másik tömb property a Vertex. Ennek minden eleme egy-egy TVertexItem típusú objektum. Nézzük most ennek a tulajdonságait. Ez az osztály három property-t tartalmaz, mely mindegyike integer típusú és Vertex1, Vertex2, illetve Vertex3 névre hallgat. Ezeken keresztül adhatjuk meg, hogy a sokszög rajzolásakor az egyes csúcspontok milyen sorrendben kövessék egymást.

Fontos tudni, hogy a komponens Vertex property-ébe mindig kettővel kevesebb elemet kell felvennünk, mint ahány eleme van a Triangles property-nek. Vagyis háromszög rajzolása esetén a Vertex csak egy elemet tartalmaz, négyszög esetén kettőt, ötszögnél hármat és így tovább.

A kirajzolás megvalósításához ismét a GradientFill függvényre lesz szükségünk mint múlt héten is, csak most a GRADIENT_FILL_TRIANGLE konstanst használjuk a rajzolásnál jelezve, hogy az átadott adatok sokszög információkat tárolnak, melyeket a komponens property-eiből állítunk elő a függvény hívása előtt úgy, hogy két ciklussal végignézzük a két tömb property-nk értékeit
procedure TTriangleGradient.Paint;
var
  vert: array of TRIVERTEX;
  gt: array of TGradientTriangle;
  i: integer;
begin
  SetLength(vert, FTriangles.Count);
  SetLength(gt, FVertex.Count);
  for i:=0 to FTriangles.Count-1 do begin
    vert[i].X:=FTriangles[i].X;
    vert[i].Y:=FTriangles[i].Y;
    vert[i].Red:=GetRValue(FTriangles[i].Color)*256;
    vert[i].Green:=GetGValue(FTriangles[i].Color)*256;
    vert[i].Blue:=GetBValue(FTriangles[i].Color)*256;
    vert[i].Alpha:=0;
  end;
  for i:=0 to FVertex.Count-1 do begin
    gt[i].Vertex1:=FVertex[i].Vertex1;
    gt[i].Vertex2:=FVertex[i].Vertex2;
    gt[i].Vertex3:=FVertex[i].Vertex3;
  end;
  GradientFill(Canvas.Handle, @vert[0], FTriangles.Count, 
     @gt[0], FVertex.Count, GRADIENT_FILL_TRIANGLE);
  SetLength(vert, 0);
  SetLength(gt, 0);
end;


GDI újdonságai cikksorozat