public override void OnCreateVertexBuffer(VertexBuffer11 vb)
        {
            ComputeMatrix();
            double latMin = 0 + (ScaleY * (Height - PixelCenterY));
            double latMax = 0 - (ScaleY * PixelCenterY);
            double lngMin = 0 + (ScaleX * PixelCenterX);
            double lngMax = 0 - (ScaleX * (Width - PixelCenterX));


            Vector3d TopLeft     = GeoTo3d(latMin, lngMin);
            Vector3d BottomRight = GeoTo3d(latMax, lngMax);
            Vector3d TopRight    = GeoTo3d(latMin, lngMax);
            Vector3d BottomLeft  = GeoTo3d(latMax, lngMin);


            // Create a vertex buffer
            PositionNormalTexturedX2[] verts = (PositionNormalTexturedX2[])vb.Lock(0, 0); // Lock the buffer (which will return our structs)

            verts[0].Position = TopLeft;
            verts[0].Normal   = TopLeft;
            verts[0].Tu       = 0;
            verts[0].Tv       = 0;
            verts[1].Position = TopRight;
            verts[1].Normal   = TopRight;
            verts[1].Tu       = 1;
            verts[1].Tv       = 0;
            verts[2].Position = BottomRight;
            verts[2].Normal   = BottomRight;
            verts[2].Tu       = 1;
            verts[2].Tv       = 1;
            verts[3].Position = BottomLeft;
            verts[3].Normal   = BottomLeft;
            verts[3].Tu       = 0;
            verts[3].Tv       = 1;
            vb.Unlock();

            short[] indexArray = (short[])indexBuffer.Lock();
            indexArray[0] = 3;
            indexArray[1] = 1;
            indexArray[2] = 0;
            indexArray[3] = 1;
            indexArray[4] = 3;
            indexArray[5] = 2;


            indexBuffer.Unlock();
        }
        public void CreateWarpVertexBuffer()
        {
            ReadWarpMeshFile();
            int warpSubX = meshX - 1;
            int warpSubY = meshY - 1;

            CleanUpWarpBuffers();


            warpIndexBuffer = new IndexBuffer11(typeof(short), (warpSubX * warpSubY * 6), RenderContext11.PrepDevice);
            warpVertexBuffer = new PositionColorTexturedVertexBuffer11(((warpSubX + 1) * (warpSubY + 1)), RenderContext11.PrepDevice);

            warpVertexCount = ((warpSubX + 1) * (warpSubY + 1));


            int index = 0;

            PositionColorTexturedVertexBuffer11 vb = warpVertexBuffer;
            // Create a vertex buffer 
            PositionColoredTextured[] verts = (PositionColoredTextured[])vb.Lock(0, 0); // Lock the buffer (which will return our structs)
            int x1, y1;



            double textureStepX = 1.0f / warpSubX;
            double textureStepY = 1.0f / warpSubY;
            for (y1 = 0; y1 <= warpSubY; y1++)
            {

                for (x1 = 0; x1 <= warpSubX; x1++)
                {

                    index = y1 * (warpSubX + 1) + x1;
                    verts[index].Position = mesh[x1, y1].Position;
                    verts[index].Tu = mesh[x1, y1].Tu;
                    verts[index].Tv = mesh[x1, y1].Tv;
                    verts[index].Color = mesh[x1, y1].Color;
                }
            }
            vb.Unlock();
            warpTriangleCount = (warpSubX) * (warpSubY) * 2;
            short[] indexArray = (short[])warpIndexBuffer.Lock();
            index = 0;
            for (y1 = 0; y1 < warpSubY; y1++)
            {
                for (x1 = 0; x1 < warpSubX; x1++)
                {
                    // First triangle in quad
                    indexArray[index] = (short)(y1 * (warpSubX + 1) + x1);
                    indexArray[index + 1] = (short)((y1 + 1) * (warpSubX + 1) + x1);
                    indexArray[index + 2] = (short)(y1 * (warpSubX + 1) + (x1 + 1));

                    // Second triangle in quad
                    indexArray[index + 3] = (short)(y1 * (warpSubX + 1) + (x1 + 1));
                    indexArray[index + 4] = (short)((y1 + 1) * (warpSubX + 1) + x1);
                    indexArray[index + 5] = (short)((y1 + 1) * (warpSubX + 1) + (x1 + 1));
                    index += 6;
                }
            }
            this.warpIndexBuffer.Unlock();
        }
        private void MakeDistortionGrid()
        {
            Bitmap bmpBlend = new Bitmap(config.BlendFile);
            FastBitmap fastBlend = new FastBitmap(bmpBlend);
            Bitmap bmpDistort = new Bitmap(config.DistortionGrid);
            FastBitmap fastDistort = new FastBitmap(bmpDistort);


            fastBlend.LockBitmapRgb();
            fastDistort.LockBitmapRgb();
            int subX = bmpBlend.Width - 1;
            int subY = subX;

            if (distortIndexBuffer != null)
            {
                distortIndexBuffer.Dispose();
                GC.SuppressFinalize(distortIndexBuffer);
            }

            if (distortVertexBuffer != null)
            {
                distortVertexBuffer.Dispose();
                GC.SuppressFinalize(distortVertexBuffer);
            }


            distortIndexBuffer = new IndexBuffer11(typeof(int), (subX * subY * 6), RenderContext11.PrepDevice);
            distortVertexBuffer = new PositionColorTexturedVertexBuffer11(((subX + 1) * (subY + 1)), RenderContext11.PrepDevice);

            distortVertexCount = (subX + 1) * (subY + 1);


            int index = 0;


            // Create a vertex buffer 
            PositionColoredTextured[] verts = (PositionColoredTextured[])distortVertexBuffer.Lock(0, 0); // Lock the buffer (which will return our structs)
            int x1, y1;

            unsafe
            {
                double maxU = 0;
                double maxV = 0;
                double textureStepX = 1.0f / subX;
                double textureStepY = 1.0f / subY;
                for (y1 = 0; y1 <= subY; y1++)
                {
                    double tv;
                    for (x1 = 0; x1 <= subX; x1++)
                    {
                        double tu;


                        index = y1 * (subX + 1) + x1;
                        PixelDataRgb* pdata = fastDistort.GetRgbPixel(x1, y1);

                        tu = (float)(pdata->blue + ((uint)pdata->red % 16) * 256) / 4095f;
                        tv = (float)(pdata->green + ((uint)pdata->red / 16) * 256) / 4095f;

                        //tu = (tu - .5f) * 1.7777778 + .5f;

                        if (tu > maxU)
                        {
                            maxU = tu;
                        }
                        if (tv > maxV)
                        {
                            maxV = tv;
                        }

                        verts[index].Position = new SharpDX.Vector4(((float)x1 / subX) - .5f, (1f - ((float)y1 / subY)) - .5f, .9f, 1f);
                        verts[index].Tu = (float)tu;
                        verts[index].Tv = (float)tv;
                        PixelDataRgb* pPixel = fastBlend.GetRgbPixel(x1, y1);

                        verts[index].Color = Color.FromArgb(255, pPixel->red, pPixel->green, pPixel->blue);

                    }
                }
                distortVertexBuffer.Unlock();
                distortTriangleCount = (subX) * (subY) * 2;
                uint[] indexArray = (uint[])distortIndexBuffer.Lock();
                index = 0;
                for (y1 = 0; y1 < subY; y1++)
                {
                    for (x1 = 0; x1 < subX; x1++)
                    {
                        // First triangle in quad
                        indexArray[index] = (uint)(y1 * (subX + 1) + x1);
                        indexArray[index + 1] = (uint)((y1 + 1) * (subX + 1) + x1);
                        indexArray[index + 2] = (uint)(y1 * (subX + 1) + (x1 + 1));

                        // Second triangle in quad
                        indexArray[index + 3] = (uint)(y1 * (subX + 1) + (x1 + 1));
                        indexArray[index + 4] = (uint)((y1 + 1) * (subX + 1) + x1);
                        indexArray[index + 5] = (uint)((y1 + 1) * (subX + 1) + (x1 + 1));
                        index += 6;
                    }
                }
                this.distortIndexBuffer.Unlock();
            }
            fastDistort.UnlockBitmap();
            fastBlend.UnlockBitmap();
            fastDistort.Dispose();
            GC.SuppressFinalize(fastDistort);
            fastBlend.Dispose();
            GC.SuppressFinalize(fastBlend);
        }
        public override bool Draw(RenderContext11 renderContext, float opacity, bool flat)
        {
            if (shapefile == null)
            {
                return(false);
            }

            if (shapeFileVertex == null)
            {
                List <Vector3> vertList       = new List <Vector3>();
                List <UInt32>  indexList      = new List <UInt32>();
                UInt32         firstItemIndex = 0;
                Vector3        lastItem       = new Vector3();
                bool           firstItem      = true;



                bool   north            = true;
                double offsetX          = 0;
                double offsetY          = 0;
                double centralMeridian  = 0;
                double mapScale         = 0;
                double standardParallel = 70;

                if (shapefile.Projection == ShapeFile.Projections.PolarStereo)
                {
                    north            = shapefile.FileHeader.ProjectionInfo.Name.ToLower().Contains("north");
                    standardParallel = shapefile.FileHeader.ProjectionInfo.GetParameter("standard_parallel_1");
                    centralMeridian  = shapefile.FileHeader.ProjectionInfo.GetParameter("central_meridian");
                    mapScale         = shapefile.FileHeader.ProjectionInfo.GetParameter("scale_factor");
                    offsetY          = shapefile.FileHeader.ProjectionInfo.GetParameter("false_easting");
                    offsetX          = shapefile.FileHeader.ProjectionInfo.GetParameter("false_northing");
                }



                UInt32 currentIndex = 0;
                Color  color        = Color;
                int    count        = 360;
                for (int i = 0; i < shapefile.Shapes.Count; i++)
                {
                    if (shapefile.Shapes[i].GetType() == typeof(Polygon))
                    {
                        Polygon p = (Polygon)shapefile.Shapes[i];

                        for (int z = 0; z < p.Rings.Length; z++)
                        {
                            count = (p.Rings[z].Points.Length);

                            // content from DBF
                            DataRow dr = p.Rings[z].Attributes;

                            for (int k = 0; k < p.Rings[z].Points.Length; k++)
                            {
                                // 2D Point coordinates. 3d also supported which would add a Z. There's also an optional measure (M) that can be used.
                                double Xcoord = p.Rings[z].Points[k].X;
                                double Ycoord = p.Rings[z].Points[k].Y;

                                if (shapefile.Projection == ShapeFile.Projections.Geo)
                                {
                                    lastItem = Coordinates.GeoTo3d(Ycoord, Xcoord);
                                }
                                else if (shapefile.Projection == ShapeFile.Projections.PolarStereo)
                                {
                                    lastItem = Coordinates.SterographicTo3d(Xcoord, Ycoord, 1, standardParallel, centralMeridian, offsetX, offsetY, mapScale, north).Vector3;
                                }

                                if (k == 0)
                                {
                                    firstItemIndex = currentIndex;
                                    firstItem      = true;
                                }

                                vertList.Add(lastItem);

                                if (firstItem)
                                {
                                    firstItem = false;
                                }
                                else
                                {
                                    indexList.Add(currentIndex);
                                    currentIndex++;
                                    indexList.Add(currentIndex);
                                }
                            }

                            indexList.Add(currentIndex);
                            indexList.Add(firstItemIndex);
                            currentIndex++;
                        }
                    }
                    else if (shapefile.Shapes[i].GetType() == typeof(PolygonZ))
                    {
                        PolygonZ p = (PolygonZ)shapefile.Shapes[i];

                        for (int z = 0; z < p.Rings.Length; z++)
                        {
                            count = (p.Rings[z].Points.Length);

                            // content from DBF
                            DataRow dr = p.Rings[z].Attributes;

                            for (int k = 0; k < p.Rings[z].Points.Length; k++)
                            {
                                // 2D Point coordinates. 3d also supported which would add a Z. There's also an optional measure (M) that can be used.
                                double Xcoord = p.Rings[z].Points[k].X;
                                double Ycoord = p.Rings[z].Points[k].Y;

                                if (shapefile.Projection == ShapeFile.Projections.Geo)
                                {
                                    lastItem = Coordinates.GeoTo3d(Ycoord, Xcoord);
                                }
                                else if (shapefile.Projection == ShapeFile.Projections.PolarStereo)
                                {
                                    lastItem = Coordinates.SterographicTo3d(Xcoord, Ycoord, 1, standardParallel, centralMeridian, offsetX, offsetY, mapScale, north).Vector3;
                                }


                                if (k == 0)
                                {
                                    firstItemIndex = currentIndex;
                                    firstItem      = true;
                                }

                                vertList.Add(lastItem);

                                if (firstItem)
                                {
                                    firstItem = false;
                                }
                                else
                                {
                                    indexList.Add(currentIndex);
                                    currentIndex++;
                                    indexList.Add(currentIndex);
                                }
                            }

                            indexList.Add(currentIndex);
                            indexList.Add(firstItemIndex);
                            currentIndex++;
                        }
                    }
                    else if (shapefile.Shapes[i].GetType() == typeof(PolyLine))
                    {
                        PolyLine p = (PolyLine)shapefile.Shapes[i];
                        for (int z = 0; z < p.Lines.Length; z++)
                        {
                            count = (p.Lines[z].Points.Length);

                            firstItem = true;
                            for (int k = 0; k < p.Lines[z].Points.Length; k++)
                            {
                                // 2D Point coordinates. 3d also supported which would add a Z. There's also an optional measure (M) that can be used.
                                double Xcoord = p.Lines[z].Points[k].X;
                                double Ycoord = p.Lines[z].Points[k].Y;
                                if (shapefile.Projection == ShapeFile.Projections.Geo)
                                {
                                    lastItem = Coordinates.GeoTo3d(Ycoord, Xcoord);
                                }
                                else if (shapefile.Projection == ShapeFile.Projections.PolarStereo)
                                {
                                    lastItem = Coordinates.SterographicTo3d(Xcoord, Ycoord, 1, standardParallel, centralMeridian, offsetX, offsetY, mapScale, north).Vector3;
                                }

                                if (k == 0)
                                {
                                    firstItemIndex = currentIndex;
                                    firstItem      = true;
                                }

                                vertList.Add(lastItem);

                                if (firstItem)
                                {
                                    firstItem = false;
                                }
                                else
                                {
                                    indexList.Add(currentIndex);
                                    currentIndex++;
                                    indexList.Add(currentIndex);
                                }
                            }
                            currentIndex++;
                        }
                    }
                    else if (shapefile.Shapes[i].GetType() == typeof(PolyLineZ))
                    {
                        PolyLineZ p = (PolyLineZ)shapefile.Shapes[i];
                        for (int z = 0; z < p.Lines.Length; z++)
                        {
                            count = (p.Lines[z].Points.Length);
                            Vector3[] points = new Vector3[(count)];

                            firstItem = true;
                            for (int k = 0; k < p.Lines[z].Points.Length; k++)
                            {
                                // 2D Point coordinates. 3d also supported which would add a Z. There's also an optional measure (M) that can be used.
                                double Xcoord = p.Lines[z].Points[k].X;
                                double Ycoord = p.Lines[z].Points[k].Y;
                                if (shapefile.Projection == ShapeFile.Projections.Geo)
                                {
                                    lastItem = Coordinates.GeoTo3d(Ycoord, Xcoord);
                                }
                                else if (shapefile.Projection == ShapeFile.Projections.PolarStereo)
                                {
                                    lastItem = Coordinates.SterographicTo3d(Xcoord, Ycoord, 1, standardParallel, centralMeridian, offsetX, offsetY, mapScale, north).Vector3;
                                }

                                if (k == 0)
                                {
                                    firstItemIndex = currentIndex;
                                    firstItem      = true;
                                }

                                vertList.Add(lastItem);

                                if (firstItem)
                                {
                                    firstItem = false;
                                }
                                else
                                {
                                    indexList.Add(currentIndex);
                                    currentIndex++;
                                    indexList.Add(currentIndex);
                                }
                            }
                            currentIndex++;
                        }
                    }
                    else if (shapefile.Shapes[i].GetType() == typeof(ShapefileTools.Point))
                    {
                        ShapefileTools.Point p = (ShapefileTools.Point)shapefile.Shapes[i];

                        // 2D Point coordinates. 3d also supported which would add a Z. There's also an optional measure (M) that can be used.
                        double Xcoord = p.X;
                        double Ycoord = p.Y;
                        if (shapefile.Projection == ShapeFile.Projections.Geo)
                        {
                            lastItem = Coordinates.GeoTo3d(Ycoord, Xcoord);
                        }
                        else if (shapefile.Projection == ShapeFile.Projections.PolarStereo)
                        {
                            lastItem = Coordinates.SterographicTo3d(Xcoord, Ycoord, 1, standardParallel, centralMeridian, offsetX, offsetY, mapScale, north).Vector3;
                        }

                        vertList.Add(lastItem);

                        currentIndex++;
                        lines = false;
                    }
                }

                shapeVertexCount = vertList.Count;
                shapeFileVertex  = new PositionVertexBuffer11(vertList.Count, RenderContext11.PrepDevice);

                Vector3[] verts   = (Vector3[])shapeFileVertex.Lock(0, 0); // Lock the buffer (which will return our structs)
                int       indexer = 0;
                foreach (Vector3 vert in vertList)
                {
                    verts[indexer++] = vert;
                }
                shapeFileVertex.Unlock();


                shapeIndexCount = indexList.Count;

                if (lines)
                {
                    if (indexList.Count > 65500)
                    {
                        isLongIndex    = true;
                        shapeFileIndex = new IndexBuffer11(typeof(UInt32), indexList.Count, RenderContext11.PrepDevice);
                    }
                    else
                    {
                        isLongIndex    = false;
                        shapeFileIndex = new IndexBuffer11(typeof(short), indexList.Count, RenderContext11.PrepDevice);
                    }

                    if (isLongIndex)
                    {
                        indexer = 0;
                        UInt32[] indexes = (UInt32[])shapeFileIndex.Lock();
                        foreach (UInt32 indexVal in indexList)
                        {
                            indexes[indexer++] = indexVal;
                        }
                        shapeFileIndex.Unlock();
                    }
                    else
                    {
                        indexer = 0;
                        short[] indexes = (short[])shapeFileIndex.Lock();
                        foreach (UInt32 indexVal in indexList)
                        {
                            indexes[indexer++] = (short)indexVal;
                        }
                        shapeFileIndex.Unlock();
                    }
                }
            }


            renderContext.DepthStencilMode = DepthStencilMode.Off;
            renderContext.BlendMode        = BlendMode.Alpha;
            SimpleLineShader11.Color       = Color.FromArgb((int)(opacity * 255), Color);

            SharpDX.Matrix mat = (renderContext.World * renderContext.View * renderContext.Projection).Matrix11;
            mat.Transpose();

            SimpleLineShader11.WVPMatrix      = mat;
            SimpleLineShader11.CameraPosition = Vector3d.TransformCoordinate(renderContext.CameraPosition, Matrix3d.Invert(renderContext.World)).Vector3;
            SimpleLineShader11.ShowFarSide    = false;
            SimpleLineShader11.Sky            = false;

            renderContext.SetVertexBuffer(shapeFileVertex);
            SimpleLineShader11.Use(renderContext.devContext);

            if (lines)
            {
                renderContext.devContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.LineList;
                renderContext.SetIndexBuffer(shapeFileIndex);
                renderContext.devContext.DrawIndexed(shapeFileIndex.Count, 0, 0);
            }
            else
            {
                renderContext.devContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.PointList;
                renderContext.devContext.Draw(shapeVertexCount, 0);
            }

            renderContext.devContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;

            return(true);
        }