public Device(Panel canvas) { this.Canvas = canvas; canvas.Paint += Redraw; PhongShadingModel = new PhongShadingModel(); }
void ProcessScanLinePhong(int y, Vertex pa, Vertex pb, Vertex pc, Vertex pd, Color color) { const double epsilon = 0.0001; var gradient1 = Math.Abs(pa.ScreenPosition.Y - pb.ScreenPosition.Y) > epsilon ? (y - pa.ScreenPosition.Y) / (pb.ScreenPosition.Y - pa.ScreenPosition.Y) : 1; var gradient2 = Math.Abs(pc.ScreenPosition.Y - pd.ScreenPosition.Y) > epsilon ? (y - pc.ScreenPosition.Y) / (pd.ScreenPosition.Y - pc.ScreenPosition.Y) : 1; int sx = (int)MathHelpers.Interpolate(pa.ScreenPosition.X, pb.ScreenPosition.X, gradient1); int ex = (int)MathHelpers.Interpolate(pc.ScreenPosition.X, pd.ScreenPosition.X, gradient2); // starting Z & ending Z double z1 = MathHelpers.Interpolate(pa.ScreenPosition.Z, pb.ScreenPosition.Z, gradient1); double z2 = MathHelpers.Interpolate(pc.ScreenPosition.Z, pd.ScreenPosition.Z, gradient2); double sx_world = MathHelpers.Interpolate(pa.Position.X, pb.Position.X, gradient1); double ex_world = MathHelpers.Interpolate(pc.Position.X, pd.Position.X, gradient2); double y1_world = MathHelpers.Interpolate(pa.Position.Y, pb.Position.Y, gradient1); double y2_world = MathHelpers.Interpolate(pc.Position.Y, pd.Position.Y, gradient2); double z1_world = MathHelpers.Interpolate(pa.Position.Z, pb.Position.Z, gradient1); double z2_world = MathHelpers.Interpolate(pc.Position.Z, pd.Position.Z, gradient2); var normal1 = MathHelpers.Interpolate(pa.Normal, pb.Normal, gradient1); var normal2 = MathHelpers.Interpolate(pc.Normal, pd.Normal, gradient2); // drawing a line from left (sx) to right (ex) if (ex < sx) { Utils.Swap(ref sx, ref ex); Utils.Swap(ref gradient1, ref gradient2); Utils.Swap(ref z1, ref z2); Utils.Swap(ref sx_world, ref ex_world); Utils.Swap(ref y1_world, ref y2_world); Utils.Swap(ref z1_world, ref z2_world); Utils.Swap(ref normal1, ref normal2); } for (var x = sx; x < ex; x++) { float gradient = (x - sx) / (float)(ex - sx); var z = MathHelpers.Interpolate(z1, z2, gradient); var x_world = MathHelpers.Interpolate(sx_world, ex_world, gradient); var y_world = MathHelpers.Interpolate(y1_world, y2_world, gradient); var z_world = MathHelpers.Interpolate(z1_world, z2_world, gradient); var normal = MathHelpers.Interpolate(normal1, normal2, gradient); normal = normal.Versor(); var lightCol = PhongShadingModel.ComputeIntensityAt( new Vertex { Normal = normal, Position = new Vector4(x_world, y_world, z_world, 1) }, CurrentCamera, color); DrawPoint(new Vector3(x, y, z), lightCol); } }