コード例 #1
0
ファイル: Line.cs プロジェクト: ymsquall/Avocation-Assemblies
        public static void DrawDDALine(Vertex2D p1, Vertex2D p2, AddPixelHandler handler, ZTestHandler zTest)
        {
            var dist = (p1 - p2).Length2D;

            // 如果长度小于2像素就只是一个点;
            if (dist < 2)
            {
                if (null != zTest && !zTest(p1.x, p1.y, p1.depth))
                {
                    return;
                }
                handler?.Invoke(p1.x, p1.y, p1.depth, p1.color);
                return;
            }
            // 绘制中心点;
            Vertex2D center = p1 + (p2 - p1) / 2;
            float    depth  = MathUtil.Interpolate(p1.depth, center.depth, 0.5f);

            if (null != zTest && !zTest(center.x, center.y, depth))
            {
                return;
            }
            // 颜色线性插值;
            Color clr = Color.FromArgb(
                (p1.color.a + p2.color.a) * 0.5f,
                (p1.color.r + p2.color.r) * 0.5f,
                (p1.color.g + p2.color.g) * 0.5f,
                (p1.color.b + p2.color.b) * 0.5f);

            if (null != handler)
            {
                handler(center.x, center.y, MathUtil.Interpolate(p1.depth, center.depth, 0.5f), clr);
            }
            // 前半段递归;
            DrawDDALine(p1, center, handler, zTest);
            // 后半段递归;
            DrawDDALine(center, p2, handler, zTest);
        }
コード例 #2
0
ファイル: Line.cs プロジェクト: ymsquall/Avocation-Assemblies
        public static void DrawBresenhamLine(Vertex2D p1, Vertex2D p2, AddPixelHandler handler, ZTestHandler zTest)
        {
            // Bresenham’s line algorithm;
            int x1 = p1.x;
            int y1 = p1.y;
            int x2 = p2.x;
            int y2 = p2.y;

            var   dx       = Math.Abs(x2 - x1);
            var   dy       = Math.Abs(y2 - y1);
            var   sx       = (x1 < x2) ? 1 : -1;
            var   sy       = (y1 < y2) ? 1 : -1;
            var   err      = dx - dy;
            float totalLen = (p1 - p2).SqrLength2D;

            if (totalLen <= 0f)
            {
                return;
            }
            float invTotalLen = 1f / totalLen;
            float p1x         = p1.x;
            float p1y         = p1.y;
            float p1d         = p1.depth;
            float p2d         = p2.depth;
            Color p1c         = p1.color;
            Color p2c         = p2.color;

            while (true)
            {
                float p1x1  = p1x - x1;
                float p1y1  = p1y - y1;
                float len   = p1x1 * p1x1 + p1y1 * p1y1;
                float ratio = len * invTotalLen;                        // MathUtil.Clamp(len / totalLen);
                ratio = ratio < 0 ? 0 : ratio;
                ratio = ratio > 1 ? 1 : ratio;
                float z1 = p1d + (p2d - p1d) * ratio;    //MathUtil.Interpolate(p1.Depth, p2.Depth, ratio);
                if (null != zTest && zTest(x1, y1, z1))
                {
                    float a   = p1c.a * ratio + p2c.a * (1f - ratio);
                    float r   = p1c.r * ratio + p2c.r * (1f - ratio);
                    float g   = p1c.g * ratio + p2c.g * (1f - ratio);
                    float b   = p1c.b * ratio + p2c.b * (1f - ratio);
                    Color clr = Color.FromArgb(a, r, g, b);
                    if (null != handler)
                    {
                        handler(x1, y1, z1, clr);
                    }
                }
                if ((x1 == x2) && (y1 == y2))
                {
                    break;
                }
                int e2 = 2 * err;
                if (e2 > -dy)
                {
                    err -= dy;
                    x1  += sx;
                }
                if (e2 < dx)
                {
                    err += dx;
                    y1  += sy;
                }
            }
        }
コード例 #3
0
ファイル: Line.cs プロジェクト: ymsquall/Avocation-Assemblies
        public static void DrawLine(Vertex2D p1, Vertex2D p2, AddPixelHandler handler, DrawLineType drawType, ZTestHandler zTest)
        {
            switch (drawType)
            {
            case DrawLineType.DDA:
                DrawDDALine(p1, p2, handler, zTest);
                break;

            case DrawLineType.Bresenham:
                DrawBresenhamLine(p1, p2, handler, zTest);
                break;
            }
        }