Beispiel #1
0
        public Device(Panel canvas)
        {
            this.Canvas   = canvas;
            canvas.Paint += Redraw;

            PhongShadingModel = new PhongShadingModel();
        }
Beispiel #2
0
        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);
            }
        }