Exemple #1
0
        void ProcessScanLine(DetailsForShading details)
        {
            var gradient1 = details.pa.Y != details.pb.Y ? (details.currentY - details.pa.Y) / (details.pb.Y - details.pa.Y) : 1;
            var gradient2 = details.pc.Y != details.pd.Y ? (details.currentY - details.pc.Y) / (details.pd.Y - details.pc.Y) : 1;

            int sx = (int)Interpolate(details.pa.X, details.pb.X, gradient1);
            int ex = (int)Interpolate(details.pc.X, details.pd.X, gradient2);

            // starting Z & ending Z
            float z1 = Interpolate(details.pa.Z, details.pb.Z, gradient1);
            float z2 = Interpolate(details.pc.Z, details.pd.Z, gradient2);

            // drawing a line from left (sx) to right (ex)
            for (var x = sx; x < ex; x++)
            {
                float gradient = (x - sx) / (float)(ex - sx);
                var   z        = Interpolate(z1, z2, gradient);

                Vertex current = new Vertex();
                current.Coordinates = new Vector3(x, details.currentY, z);

                Color color = shadingMachine.GetColorPerPixel(current, details);
                DrawPoint(current.Coordinates, color);
            }
        }
        public override DetailsForShading GetDetailsForShading(Vertex v1, Vertex v2, Vertex v3)
        {
            DetailsForShading details = new DetailsForShading();

            details.v1              = v1;
            details.v2              = v2;
            details.v3              = v3;
            details.area            = CalculateArea(v1.Coordinates, v2.Coordinates, v3.Coordinates);
            details.lightParameters = meshLightParameters;

            return(details);
        }
        public override Color GetColorPerPixel(Vertex vertex, DetailsForShading details)
        {
            (double alpha, double beta, double gamma) = CalculateAlphaBetaGammaForVertex(vertex.Coordinates, details);
            float r = (float)(alpha * details.v1Color.R / 255 + beta * details.v2Color.R / 255 + gamma * details.v3Color.R / 255);
            float g = (float)(alpha * details.v1Color.G / 255 + beta * details.v2Color.G / 255 + gamma * details.v3Color.G / 255);
            float b = (float)(alpha * details.v1Color.B / 255 + beta * details.v2Color.B / 255 + gamma * details.v3Color.B / 255);
            int   R = (int)(r * 255);
            int   G = (int)(g * 255);
            int   B = (int)(b * 255);

            (R, G, B) = ValidateRGB(R, G, B);

            return(Color.FromArgb(R, G, B));
        }
        public override DetailsForShading GetDetailsForShading(Vertex v1, Vertex v2, Vertex v3)
        {
            DetailsForShading details = new DetailsForShading();

            details.v1Color = ComputeColorPerVertex(v1);
            details.v2Color = ComputeColorPerVertex(v2);
            details.v3Color = ComputeColorPerVertex(v3);
            details.v1      = v1;
            details.v2      = v2;
            details.v3      = v3;
            details.area    = CalculateArea(v1.Coordinates, v2.Coordinates, v3.Coordinates);

            return(details);
        }
        public override Color GetColorPerPixel(Vertex vertex, DetailsForShading details)
        {
            (double alpha, double beta, double gamma) = CalculateAlphaBetaGammaForVertex(vertex.Coordinates, details);
            Vector3 normal = (float)alpha * details.v1.Normal + (float)beta * details.v2.Normal + (float)gamma * details.v3.Normal;

            normal.Normalize();
            Vector3 wcoordinates = (float)alpha * details.v1.WorldCoordinates + (float)beta * details.v2.WorldCoordinates + (float)gamma * details.v3.WorldCoordinates;

            vertex.Normal           = normal;
            vertex.WorldCoordinates = wcoordinates;

            Color color = ComputeColorPerVertex(vertex);

            return(color);
        }
        public override DetailsForShading GetDetailsForShading(Vertex v1, Vertex v2, Vertex v3)
        {
            Vector3 vNormal      = (v1.Normal + v2.Normal + v3.Normal) / 3;
            Vector3 vCenterPoint = (v1.WorldCoordinates + v2.WorldCoordinates + v3.WorldCoordinates) / 3;

            Vertex v = new Vertex();

            v.Normal           = vNormal;
            v.WorldCoordinates = vCenterPoint;

            DetailsForShading details = new DetailsForShading();

            details.globalColor = ComputeColorPerVertex(v);

            return(details);
        }
Exemple #7
0
        public void DrawTriangle(Vertex v1, Vertex v2, Vertex v3, MeshLightParameters lightParameters)
        {
            // Sorting the points in order to always have this order on screen p1, p2 & p3
            // with p1 always up (thus having the Y the lowest possible to be near the top screen)
            // then p2 between p1 & p3
            if (v1.Coordinates.Y > v2.Coordinates.Y)
            {
                var temp = v2;
                v2 = v1;
                v1 = temp;
            }

            if (v2.Coordinates.Y > v3.Coordinates.Y)
            {
                var temp = v2;
                v2 = v3;
                v3 = temp;
            }

            if (v1.Coordinates.Y > v2.Coordinates.Y)
            {
                var temp = v2;
                v2 = v1;
                v1 = temp;
            }

            Vector3 p1 = v1.Coordinates;
            Vector3 p2 = v2.Coordinates;
            Vector3 p3 = v3.Coordinates;

            DetailsForShading details = shadingMachine.GetDetailsForShading(v1, v2, v3);

            // computing lines' directions
            float dP1P2, dP1P3;

            // http://en.wikipedia.org/wiki/Slope
            // Computing slopes
            if (p2.Y - p1.Y > 0)
            {
                dP1P2 = (p2.X - p1.X) / (p2.Y - p1.Y);
            }
            else
            {
                dP1P2 = 0;
            }

            if (p3.Y - p1.Y > 0)
            {
                dP1P3 = (p3.X - p1.X) / (p3.Y - p1.Y);
            }
            else
            {
                dP1P3 = 0;
            }

            // First case where triangles are like that:
            // P1
            // -
            // --
            // - -
            // -  -
            // -   - P2
            // -  -
            // - -
            // -
            // P3
            if (dP1P2 > dP1P3)
            {
                for (var y = (int)p1.Y; y <= (int)p3.Y; y++)
                {
                    //data.currentY = y;
                    details.currentY = y;
                    if (y < p2.Y)
                    {
                        details.pa = v1.Coordinates;
                        details.pb = v3.Coordinates;
                        details.pc = v1.Coordinates;
                        details.pd = v2.Coordinates;
                        //ProcessScanLine(data, v1, v3, v1, v2, details.globalColor);
                        ProcessScanLine(details);
                    }
                    else
                    {
                        details.pa = v1.Coordinates;
                        details.pb = v3.Coordinates;
                        details.pc = v2.Coordinates;
                        details.pd = v3.Coordinates;
                        // ProcessScanLine(data, v1, v3, v2, v3, details.globalColor);
                        ProcessScanLine(details);
                    }
                }
            }
            // First case where triangles are like that:
            //       P1
            //        -
            //       --
            //      - -
            //     -  -
            // P2 -   -
            //     -  -
            //      - -
            //        -
            //       P3
            else
            {
                for (var y = (int)p1.Y; y <= (int)p3.Y; y++)
                {
                    //data.currentY = y;
                    details.currentY = y;
                    if (y < p2.Y)
                    {
                        details.pa = v1.Coordinates;
                        details.pb = v2.Coordinates;
                        details.pc = v1.Coordinates;
                        details.pd = v3.Coordinates;
                        //ProcessScanLine(data, v1, v2, v1, v3, details.globalColor);
                        ProcessScanLine(details);
                    }
                    else
                    {
                        details.pa = v2.Coordinates;
                        details.pb = v3.Coordinates;
                        details.pc = v1.Coordinates;
                        details.pd = v3.Coordinates;
                        // ProcessScanLine(data, v2, v3, v1, v3, details.globalColor);
                        ProcessScanLine(details);
                    }
                }
            }
        }
 public abstract Color GetColorPerPixel(Vertex vertex, DetailsForShading details);
 public override Color GetColorPerPixel(Vertex vertex, DetailsForShading details)
 {
     return(details.globalColor);
 }
        protected (double alpha, double beta, double gamma) CalculateAlphaBetaGammaForVertex(Vector3 v, DetailsForShading details)
        {
            double a, b, g;
            double areaA, areaB, areaG;

            areaA = CalculateArea(v, details.v2.Coordinates, details.v3.Coordinates);
            areaB = CalculateArea(v, details.v1.Coordinates, details.v3.Coordinates);
            areaG = CalculateArea(v, details.v1.Coordinates, details.v2.Coordinates);
            a     = areaA / details.area;
            b     = areaB / details.area;
            g     = areaG / details.area;
            return(a, b, g);
        }