public void DrawTriangle(Vertex a, Vertex b, Vertex c) { a = SpaceToScreen(a); b = SpaceToScreen(b); c = SpaceToScreen(c); if (a.Coordinate.Y > b.Coordinate.Y) { Swap(ref a, ref b); } if (a.Coordinate.Y > c.Coordinate.Y) { Swap(ref a, ref c); } if (b.Coordinate.Y > c.Coordinate.Y) { Swap(ref b, ref c); } Vertex left = new Vertex(); Vertex right = new Vertex(); Vertex point = new Vertex(); for (double y = a.Coordinate.Y; y < c.Coordinate.Y; ++y) { if (y < 0 || y > (Height - 1)) { continue; } bool topHalf = y < b.Coordinate.Y; var a0 = a; var a1 = c; Interpolate(a0, a1, (y - a0.Coordinate.Y) / (a1.Coordinate.Y - a0.Coordinate.Y), ref left); var b0 = topHalf ? a : b; var b1 = topHalf ? b : c; Interpolate(b0, b1, (y - b0.Coordinate.Y) / (b1.Coordinate.Y - b0.Coordinate.Y), ref right); if (left.Coordinate.X > right.Coordinate.X) { Swap(ref left, ref right); } for (double x = left.Coordinate.X; x < right.Coordinate.X; ++x) { if (x < 0 || x > (Width - 1)) { continue; } Interpolate(left, right, (x - left.Coordinate.X) / (right.Coordinate.X - left.Coordinate.X), ref point); if (point.Coordinate.Z > 1 || point.Coordinate.Z < -1) { continue; } if (point.Coordinate.Z < ZBuffer[(int)x, (int)y]) { ZBuffer[(int)x, (int)y] = point.Coordinate.Z; ColorBuffer.SetPixel((int)x, (int)y, point.Color); } } } }
private Vertex SpaceToScreen(Vertex vertex) { return(new Vertex(SpaceToScreenCoordinate(vertex.Coordinate), vertex.Normal, vertex.Color)); }
private void Interpolate(Vertex a, Vertex b, double f, ref Vertex v) { v.Coordinate = Interpolate(a.Coordinate, b.Coordinate, f); v.Normal = Interpolate(a.Normal, b.Normal, f); v.Color = Interpolate(a.Color, b.Color, f); }