Example #1
0
 public BitmapSurface(BitmapSurface surface, int width, int height) : this(width, height)
 {
     if (BmpSource.PixelFormat != surface.BmpSource.PixelFormat)
         throw new ArgumentException("У исходной поверхности должен быть тот же формат пикселя");
     lock (surface.LockObject) {
         lock (LockObject) {
             var count = Math.Min(stride, surface.stride);
             var lines = Math.Min(Height, surface.Height);
             var block = lines / Environment.ProcessorCount;
             Parallel.For(0, Environment.ProcessorCount, (int i) => {
                 var srcptr = surface.ImageBits + surface.stride * block * i - surface.stride;
                 var dstptr = ImageBits + stride * block * i - stride;
                 for (int j = block; j > 0; --j)
                     #if NETFX_46
                     Buffer.MemoryCopy(srcptr += surface.stride, dstptr += stride, stride, count));
                     #else
                     MemCpy._memcpy_uu(dstptr += stride, srcptr += surface.stride, count);
                     #endif       
             });
             lines -= block * Environment.ProcessorCount;
             block *= Environment.ProcessorCount;
             var srclpi = surface.ImageBits + surface.stride * (block - 1);
             var dstlpi = ImageBits + stride * (block - 1);
             for (int j = lines; j > 0; --j)
                 #if NETFX_46
                 Buffer.MemoryCopy(srclpi += surface.stride, dstlpi += stride, stride, count));
                 #else
                 MemCpy._memcpy_uu(dstlpi += stride, srclpi += surface.stride, count);
                 #endif    
         }
     }   
 }
Example #2
0
        private void Initialize(int width, int height)
        {
            if (width == _BI.biHeader.bihWidth && height == -_BI.biHeader.bihHeight)
                return;
            
            lock (LockObj)
            {
                if (_GFX != null) _GFX.Dispose();
                if (_DIB != null) _DIB.Dispose();

                _DIB = new BitmapSurface(width, height);
                _GFX = GDIGraphics.FromImage(_DIB.BmpSource);
                _GFX.CompositingQuality = _gfxcompq;
                _GFX.CompositingMode = _gfxcompm;
                _GFX.SmoothingMode = _gfxsmoth;
                _DIB.DrawQuality = _dibdmode;

                _BI  = new BITMAPINFO {
				    biHeader = {
					    bihBitCount = 32,
					    bihPlanes   = 1,
					    bihSize     = 40,
					    bihWidth    = +width,
					    bihHeight   = -height,
                        bihSizeImage = (width * height) << 2
				    }
			    };
            }
        }
Example #3
0
 public static unsafe void FillRectangle(this BitmapSurface surface, int color, int sx, int sy, int width, int height)
 {
     unchecked {
         if (!Drawing.ClipRect(surface.Clipper, ref sx, ref sy, ref width, ref height))
         {
             return;
         }
         Drawing.FillRectangle((int *)surface.ImageBits, surface.Width, color, sx, sy, width, height);
     }
 }
Example #4
0
 public static unsafe void DrawLine(this BitmapSurface surface, int color, double x1, double y1, double x2, double y2)
 {
     if (!Drawing.Clip2D(surface.Clipper, ref x1, ref y1, ref x2, ref y2))
     {
         return;
     }
     if (surface.DrawQuality == SurfaceDrawQuality.High)
     {
         Drawing.DrawLineHQ((int *)surface.ImageBits, surface.Width, color, x1, y1, x2, y2);
     }
     else
     {
         Drawing.DrawLineLQ((int *)surface.ImageBits, surface.Width, color,
                            (int)(x1 + 0.5), (int)(y1 + 0.5), (int)(x2 + 0.5), (int)(y2 + 0.5));
     }
 }
Example #5
0
        public static unsafe void DrawTriangle(this BitmapSurface surface, int color1, double x1, double y1, int color2, double x2, double y2, int color3, double x3, double y3)
        {
            if (surface.Clipper.PointsInBounds(x1, y1, x2, y2, x3, y3))
            {
                Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color1, x1, y1, color2, x2, y2, color3, x3, y3);
                return;
            }

            // NOTE: Отсутсвует реализация частных случаев триангуляции, когда две или три грани полностью отсекаются

            // Соотношение старых и новых координат после отсечения:
            //
            //                 (_x1,_y1)
            //                     O 1
            //                    / \
            //           (x0,y0) /   \ (x1,y1)
            //                --+-----+--
            //               \ /       \ /
            //        (x2,y2) +         + (x3,y3)
            //               / \       / \
            //            2 /   \     /   \ 3
            //   (_x2,_y2) O ----+---+---- O (_x3,_y3)
            //             (x4,y4)\ /(x5,y5)
            int    trimed;
            double _x1 = x1, _y1 = y1, _x2 = x2, _y2 = y2, _x3 = x3, _y3 = y3;
            double x0 = x1, y0 = y1, x4 = x2, y4 = y2, x5 = x3, y5 = y3;

            if (!Drawing.Clip2D(surface.Clipper, ref x0, ref y0, ref x2, ref y2))
            {
                if (!Drawing.Clip2D(surface.Clipper, ref x1, ref y1, ref x3, ref y3))
                {
                    if (!Drawing.Clip2D(surface.Clipper, ref x4, ref y4, ref x5, ref y5))
                    {
                        return; // все грани не определены
                    }
                    else
                    {
                        return; // грани 1-2 и 1-3 не определены
                    }
                }
                else if (!Drawing.Clip2D(surface.Clipper, ref x4, ref y4, ref x5, ref y5))
                {
                    return; // грани 1-2 и 2-3 не определены
                }
                else
                {
                    x0     = x1;  y0 = y1;  x2 = x4;  y2 = y4;
                    trimed = ((x3 == _x3 && y3 == _y3 && x5 == _x3 && y5 == _y3) ? 11 : 15);
                }
            }
            else if (!Drawing.Clip2D(surface.Clipper, ref x1, ref y1, ref x3, ref y3))
            {
                if (!Drawing.Clip2D(surface.Clipper, ref x4, ref y4, ref x5, ref y5))
                {
                    return; // грани 1-3 и 2-3 не определены
                }
                else
                {
                    x1     = x0;  y1 = y0;  x3 = x5;  y3 = y5;
                    trimed = ((x2 == _x2 && y2 == _y2 && x4 == _x2 && y4 == _y2) ? 13 : 15);
                }
            }
            else if (!Drawing.Clip2D(surface.Clipper, ref x4, ref y4, ref x5, ref y5))
            {
                x4     = x2;  y4 = y2;  x5 = x3;  y5 = y3;
                trimed = ((x0 == _x1 && y0 == _y1 && x1 == _x1 && y1 == _y1) ? 14 : 15);
            }
            else
            {
                trimed = ((x0 == _x1 && y0 == _y1 && x1 == _x1 && y1 == _y1) ? 0 : 1)
                         | ((x2 == _x2 && y2 == _y2 && x4 == _x2 && y4 == _y2) ? 0 : 2)
                         | ((x3 == _x3 && y3 == _y3 && x5 == _x3 && y5 == _y3) ? 0 : 4);
            }

            int c0, c1, c2, c3, c4, c5;

            Drawing.FColor _c1 = color1, _c2 = color2, _c3 = color3;
            if ((trimed & 3) != 0)
            {
                var cd = (_c2 - _c1) / (float)Math.Sqrt((_x2 - _x1) * (_x2 - _x1) + (_y2 - _y1) * (_y2 - _y1));
                c0 = _c1 + cd * (float)Math.Sqrt((x0 - _x1) * (x0 - _x1) + (y0 - _y1) * (y0 - _y1));
                c2 = _c1 + cd * (float)Math.Sqrt((x2 - _x1) * (x2 - _x1) + (y2 - _y1) * (y2 - _y1));
            }
            else
            {
                c0 = color1; c2 = color2;
            }
            if ((trimed & 5) != 0)
            {
                var cd = (_c3 - _c1) / (float)Math.Sqrt((_x3 - _x1) * (_x3 - _x1) + (_y3 - _y1) * (_y3 - _y1));
                c1 = _c1 + cd * (float)Math.Sqrt((x1 - _x1) * (x1 - _x1) + (y1 - _y1) * (y1 - _y1));
                c3 = _c1 + cd * (float)Math.Sqrt((x3 - _x1) * (x3 - _x1) + (y3 - _y1) * (y3 - _y1));
            }
            else
            {
                c1 = color1; c3 = color3;
            }
            if ((trimed & 6) != 0)
            {
                var cd = (_c3 - _c2) / (float)Math.Sqrt((_x3 - _x2) * (_x3 - _x2) + (_y3 - _y2) * (_y3 - _y2));
                c4 = _c2 + cd * (float)Math.Sqrt((x4 - _x2) * (x4 - _x2) + (y4 - _y2) * (y4 - _y2));
                c5 = _c2 + cd * (float)Math.Sqrt((x5 - _x2) * (x5 - _x2) + (y5 - _y2) * (y5 - _y2));
            }
            else
            {
                c4 = color2; c5 = color3;
            }

            switch (trimed)
            {
            case 11: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color3, x3, y3, c1, x1, y1, c4, x4, y4);
                return;

            case 13: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color2, x2, y2, c0, x0, y0, c5, x5, y5);
                return;

            case 14: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color1, x1, y1, c2, x2, y2, c3, x3, y3);
                return;

            case  1: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color2, x2, y2, color3, x3, y3, c0, x0, y0);
                Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color3, x3, y3, c0, x0, y0, c1, x1, y1);
                return;

            case  2: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color1, x1, y1, color3, x3, y3, c4, x4, y4);
                Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color1, x1, y1, c4, x4, y4, c2, x2, y2);
                return;

            case  4: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color1, x1, y1, color2, x2, y2, c3, x3, y3);
                Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color2, x2, y2, c3, x3, y3, c5, x5, y5);
                return;

            case  3: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color3, x3, y3, c1, x1, y1, c0, x0, y0);
                Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color3, x3, y3, c0, x0, y0, c2, x2, y2);
                Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color3, x3, y3, c2, x2, y2, c4, x4, y4);
                return;

            case  5: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color2, x2, y2, c0, x0, y0, c1, x1, y1);
                Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color2, x2, y2, c1, x1, y1, c3, x3, y3);
                Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color2, x2, y2, c3, x3, y3, c5, x5, y5);
                return;

            case  6: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color1, x1, y1, c2, x2, y2, c4, x4, y4);
                Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color1, x1, y1, c4, x4, y4, c5, x5, y5);
                Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color1, x1, y1, c5, x5, y5, c3, x3, y3);
                return;

            case 15:
            case  7: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, c0, x0, y0, c1, x1, y1, c3, x3, y3);
                Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, c0, x0, y0, c2, x2, y2, c4, x4, y4);
                Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, c0, x0, y0, c3, x3, y3, c5, x5, y5);
                Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, c0, x0, y0, c4, x4, y4, c5, x5, y5);
                return;

            default: throw new NotImplementedException();
            }
        }
 public static void DrawTriangle(this BitmapSurface surface, int color, DVector2 p1, DVector2 p2, DVector2 p3)
 {
     unchecked {
         DrawTriangle(surface, color, p1.X, p1.Y, p2.X, p2.Y, p3.X, p3.Y);
     }
 }
        public static unsafe void DrawTriangle(this BitmapSurface surface, int color, double x1, double y1, double x2, double y2, double x3, double y3)
        {
            unchecked {
                if (surface.Clipper.PointsInBounds(x1, y1, x2, y2, x3, y3))
                {
                    Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x1, y1, x2, y2, x3, y3);
                    return;
                }

                // NOTE: Отсутсвует реализация частных случаев триангуляции, когда две или три грани полностью отсекаются

                // Соотношение старых и новых координат после отсечения:
                //
                //                 (_x1,_y1)
                //                     O 1
                //                    / \
                //           (x0,y0) /   \ (x1,y1)
                //                --+-----+--
                //               \ /       \ /
                //        (x2,y2) +         + (x3,y3)
                //               / \       / \
                //            2 /   \     /   \ 3
                //   (_x2,_y2) O ----+---+---- O (_x3,_y3)
                //             (x4,y4)\ /(x5,y5)
                int    trimed;
                double _x1 = x1, _y1 = y1, _x2 = x2, _y2 = y2, _x3 = x3, _y3 = y3;
                double x0 = x1, y0 = y1, x4 = x2, y4 = y2, x5 = x3, y5 = y3;
                if (!Drawing.Clip2D(surface.Clipper, ref x0, ref y0, ref x2, ref y2))
                {
                    if (!Drawing.Clip2D(surface.Clipper, ref x1, ref y1, ref x3, ref y3))
                    {
                        if (!Drawing.Clip2D(surface.Clipper, ref x4, ref y4, ref x5, ref y5))
                        {
                            return; // все грани не определены
                        }
                        else
                        {
                            return; // грани 1-2 и 1-3 не определены
                        }
                    }
                    else if (!Drawing.Clip2D(surface.Clipper, ref x4, ref y4, ref x5, ref y5))
                    {
                        return; // грани 1-2 и 2-3 не определены
                    }
                    else
                    {
                        x0     = x1;  y0 = y1;  x2 = x4;  y2 = y4;
                        trimed = ((x3 == _x3 && y3 == _y3 && x5 == _x3 && y5 == _y3) ? 11 : 15);
                    }
                }
                else if (!Drawing.Clip2D(surface.Clipper, ref x1, ref y1, ref x3, ref y3))
                {
                    if (!Drawing.Clip2D(surface.Clipper, ref x4, ref y4, ref x5, ref y5))
                    {
                        return; // грани 1-3 и 2-3 не определены
                    }
                    else
                    {
                        x1     = x0;  y1 = y0;  x3 = x5;  y3 = y5;
                        trimed = ((x2 == _x2 && y2 == _y2 && x4 == _x2 && y4 == _y2) ? 13 : 15);
                    }
                }
                else if (!Drawing.Clip2D(surface.Clipper, ref x4, ref y4, ref x5, ref y5))
                {
                    x4     = x2;  y4 = y2;  x5 = x3;  y5 = y3;
                    trimed = ((x0 == _x1 && y0 == _y1 && x1 == _x1 && y1 == _y1) ? 14 : 15);
                }
                else
                {
                    trimed = ((x0 == _x1 && y0 == _y1 && x1 == _x1 && y1 == _y1) ? 0 : 1)
                             | ((x2 == _x2 && y2 == _y2 && x4 == _x2 && y4 == _y2) ? 0 : 2)
                             | ((x3 == _x3 && y3 == _y3 && x5 == _x3 && y5 == _y3) ? 0 : 4);
                }

                switch (trimed)
                {
                case 11: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x3, y3, x1, y1, x4, y4);
                    return;

                case 13: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x2, y2, x0, y0, x5, y5);
                    return;

                case 14: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x1, y1, x2, y2, x3, y3);
                    return;

                case  1: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x2, y2, x3, y3, x0, y0);
                    Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x3, y3, x0, y0, x1, y1);
                    return;

                case  2: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x1, y1, x3, y3, x4, y4);
                    Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x1, y1, x4, y4, x2, y2);
                    return;

                case  4: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x1, y1, x2, y2, x3, y3);
                    Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x2, y2, x3, y3, x5, y5);
                    return;

                case  3: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x3, y3, x1, y1, x0, y0);
                    Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x3, y3, x0, y0, x2, y2);
                    Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x3, y3, x2, y2, x4, y4);
                    return;

                case  5: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x2, y2, x0, y0, x1, y1);
                    Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x2, y2, x1, y1, x3, y3);
                    Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x2, y2, x3, y3, x5, y5);
                    return;

                case  6: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x1, y1, x2, y2, x4, y4);
                    Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x1, y1, x4, y4, x5, y5);
                    Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x1, y1, x5, y5, x3, y3);
                    return;

                case 15:
                case  7: Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x0, y0, x1, y1, x3, y3);
                    Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x0, y0, x2, y2, x4, y4);
                    Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x0, y0, x3, y3, x5, y5);
                    Drawing.DrawTriangleLQ((int *)surface.ImageBits, surface.Width, color, x0, y0, x4, y4, x5, y5);
                    return;

                default: throw new NotImplementedException();
                }
            }
        }
 public static void DrawLine(this BitmapSurface surface, int color, DVector4 p1, DVector4 p2)
 {
     unchecked {
         DrawLine(surface, color, p1.X, p1.Y, p2.X, p2.Y);
     }
 }
Example #9
0
 public Clipper(BitmapSurface surface)
 {
     X1 = Y1 = 0;
     X2 = surface.Width - 1;
     Y2 = surface.Height - 1;
 }