internal void RasterizeTriangle(CGContext context, PointF vt1, PointF vt2, PointF vt3, Color colorV1, Color colorV2, Color colorV3)
{
// get the bounding box of the triangle
int maxX = (int)Math.Max(vt1.X, Math.Max(vt2.X, vt3.X));
int minX = (int)Math.Min(vt1.X, Math.Min(vt2.X, vt3.X));
int maxY = (int)Math.Max(vt1.Y, Math.Max(vt2.Y, vt3.Y));
int minY = (int)Math.Min(vt1.Y, Math.Min(vt2.Y, vt3.Y));
// Barycentric coordinates at minX/minY corner
PointF pm = new PointF( minX, minY );
var edge32 = new Edge(vt3, vt2, vt1, pm, colorV1);
var edge13 = new Edge (vt1, vt3, vt2, pm, colorV2);
var edge21 = new Edge (vt2, vt1, vt3, pm, colorV3);
int span32 = edge32.EdgeOrigin;
int span13 = edge13.EdgeOrigin;
int span21 = edge21.EdgeOrigin;
edge32Red = colorV1.R;
edge32Green = colorV1.G;
edge32Blue = colorV1.B;
edge32Alpha = colorV1.A;
edge13Red = colorV2.R;
edge13Green = colorV2.G;
edge13Blue = colorV2.B;
edge13Alpha = colorV2.A;
edge21Red = colorV3.R;
edge21Green = colorV3.G;
edge21Blue = colorV3.B;
edge21Alpha = colorV3.A;
int span32XOffset = 0;
int span13XOffset = 0;
int span21XOffset = 0;
bool inside = false;
int mask = 0;
// Iterate over each pixel of bounding box and check if it's inside
// the triangle using the barycentirc approach.
for (int y = minY; y <= maxY; y += Edge.StepYSize)
{
// Barycentric coordinates at start of row
span32XOffset = span32;
span13XOffset = span13;
span21XOffset = span21;
inside = false;
for (int x = minX; x <= maxX; x += Edge.StepXSize)
{
mask = span32XOffset | span13XOffset | span21XOffset;
// If p is on or inside all edges for any pixels,
// render those pixels.
if (mask >= 0)
{
if (!inside)
{
inside = true;
}
RenderPixels(context, x, y, edge32, edge13, edge21, span32XOffset, span13XOffset, span21XOffset);
}
// Step to the right
span32XOffset += edge32.StepX;
span13XOffset += edge13.StepX;
span21XOffset += edge21.StepX;
if (mask < 0 && inside)
{
inside = false;
break;
}
}
// Row step
span32 += edge32.StepY;
span13 += edge13.StepY;
span21 += edge21.StepY;
}
}