コード例 #1
0
        private void DrawTriangle(Vertex v1, Vertex v2, Vertex v3, Color4 colour, Texture texture)
        {
            // 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;

            // computing the cos of the angle between the light vector and the normal vector
            // it will return a value between 0 and 1 that will be used as the intensity of the colour
            float nl1 = ComputeNDotL(v1.WorldCoordinates, v1.Normal, _lightPos);
            float nl2 = ComputeNDotL(v2.WorldCoordinates, v2.Normal, _lightPos);
            float nl3 = ComputeNDotL(v3.WorldCoordinates, v3.Normal, _lightPos);

            // computing lines' directions
            // http://en.wikipedia.org/wiki/Slope
            // Computing slopes
            float dP1P2 = p2.Y - p1.Y > 0 ? (p2.X - p1.X) / (p2.Y - p1.Y) : 0;

            float dP1P3 = p3.Y - p1.Y > 0 ? (p3.X - p1.X) / (p3.Y - p1.Y) : 0;

            if (dP1P2 > dP1P3)
            {
                // Where triangles are like:
                // P1
                // - -
                // -   - P2
                // -  -
                // P3
                DrawRightTriangle(
                    colour, texture,
                    p1, p2, p3,
                    v1, v2, v3,
                    nl1, nl2, nl3);
            }
            else
            {
                // Where triangles are like:
                //       P1
                //     -  -
                // P2 -   -
                //     -  -
                //       P3
                DrawLeftTriangle(
                    colour, texture,
                    p1, p2, p3,
                    v1, v2, v3,
                    nl1, nl2, nl3);
            }
        }
コード例 #2
0
        // drawing line between 2 points from left to right
        // papb -> pcpd
        // pa, pb, pc, pd must then be sorted before
        // drawing line between 2 points from left to right
        // papb -> pcpd
        // pa, pb, pc, pd must then be sorted before
        private void ProcessScanLine(ScanLineData data, Vertex va, Vertex vb, Vertex vc, Vertex vd, Color4 colour, Texture texture)
        {
            Vector3 pa = va.Coordinates;
            Vector3 pb = vb.Coordinates;
            Vector3 pc = vc.Coordinates;
            Vector3 pd = vd.Coordinates;

            // Thanks to current Y, we can compute the gradient to compute others values like
            // the starting X (sx) and ending X (ex) to draw between
            // if pa.Y == pb.Y or pc.Y == pd.Y, gradient is forced to 1
            var gradient1 = pa.Y != pb.Y ? (data.currentY - pa.Y) / (pb.Y - pa.Y) : 1;
            var gradient2 = pc.Y != pd.Y ? (data.currentY - pc.Y) / (pd.Y - pc.Y) : 1;

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

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

            // Interpolating normals on Y
            var snl = Interpolate(data.ndotla, data.ndotlb, gradient1);
            var enl = Interpolate(data.ndotlc, data.ndotld, gradient2);

            // Interpolating texture coordinates on Y
            var su = Interpolate(data.ua, data.ub, gradient1);
            var eu = Interpolate(data.uc, data.ud, gradient2);
            var sv = Interpolate(data.va, data.vb, gradient1);
            var ev = Interpolate(data.vc, data.vd, gradient2);

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

                // Interpolating Z, normal and texture coordinates on X
                var z     = Interpolate(z1, z2, gradient);
                var ndotl = Interpolate(snl, enl, gradient);
                var u     = Interpolate(su, eu, gradient);
                var v     = Interpolate(sv, ev, gradient);

                Color4 textureColour = texture != null
                    ? textureColour = texture.Map(u, v)
                    : textureColour = new Color4(1, 1, 1, 1);

                // changing the native colour value using the cosine of the angle
                // between the light vector and the normal vector
                // and the texture colour
                DrawPoint(new Vector3(x, data.currentY, z), colour * ndotl * textureColour);
            }
        }