protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { DateTime start = DateTime.Now; if (this.DesignMode) { return; } if (area.LocationMiddle.Lat == 0 && area.LocationMiddle.Lng == 0) { return; } try { base.OnPaint(e); } catch { return; } utmzone = center.GetUTMZone(); double heightscale = 1;//(step/90.0)*5; var campos = convertCoords(center); cameraX = campos[0]; cameraY = campos[1]; cameraZ = (campos[2] < srtm.getAltitude(center.Lat, center.Lng).alt) ? (srtm.getAltitude(center.Lat, center.Lng).alt + 1) * heightscale : center.Alt * heightscale; // (srtm.getAltitude(lookZ, lookX, 20) + 100) * heighscale; lookX = campos[0] + Math.Sin(MathHelper.Radians(rpy.Z)) * 100; lookY = campos[1] + Math.Cos(MathHelper.Radians(rpy.Z)) * 100; lookZ = cameraZ; var size = 20000; // in front PointLatLngAlt front = center.newpos(rpy.Z, size); // behind PointLatLngAlt behind = center.newpos(rpy.Z, -50); // left : 90 allows for 180 degree viewing angle PointLatLngAlt left = center.newpos(rpy.Z - 45, size); // right PointLatLngAlt right = center.newpos(rpy.Z + 45, size); double maxlat = Math.Max(left.Lat, Math.Max(right.Lat, Math.Max(front.Lat, behind.Lat))); double minlat = Math.Min(left.Lat, Math.Min(right.Lat, Math.Min(front.Lat, behind.Lat))); double maxlng = Math.Max(left.Lng, Math.Max(right.Lng, Math.Max(front.Lng, behind.Lng))); double minlng = Math.Min(left.Lng, Math.Min(right.Lng, Math.Min(front.Lng, behind.Lng))); area = RectLatLng.FromLTRB(minlng, maxlat, maxlng, minlat); zoom = 20; float screenscale = 1;//this.Width/(float) this.Height*1f; //if(!Context.IsCurrent) MakeCurrent(); GL.MatrixMode(MatrixMode.Projection); OpenTK.Matrix4 projection = OpenTK.Matrix4.CreatePerspectiveFieldOfView((float)(90 * MathHelper.deg2rad), screenscale, 0.00000001f, (float)20000); GL.LoadMatrix(ref projection); Console.WriteLine("cam: {0} {1} {2} lookat: {3} {4} {5}", (float)cameraX, (float)cameraY, (float)cameraZ, (float)lookX, (float)lookY, (float)lookZ); Matrix4 modelview = Matrix4.LookAt((float)cameraX, (float)cameraY, (float)cameraZ + 100f * 0, (float)lookX, (float)lookY, (float)lookZ, 0, 0, 1); GL.MatrixMode(MatrixMode.Modelview); // roll modelview = Matrix4.Mult(modelview, Matrix4.CreateRotationZ((float)(rpy.X * MathHelper.deg2rad))); // pitch modelview = Matrix4.Mult(modelview, Matrix4.CreateRotationX((float)(rpy.Y * -MathHelper.deg2rad))); GL.LoadMatrix(ref modelview); GL.ClearColor(Color.CornflowerBlue); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.AccumBufferBit); GL.LightModel(LightModelParameter.LightModelAmbient, new float[] { 1f, 1f, 1f, 1f }); GL.Disable(EnableCap.Fog); GL.Enable(EnableCap.Fog); //GL.Enable(EnableCap.Lighting); //GL.Enable(EnableCap.Light0); GL.Fog(FogParameter.FogColor, new float[] { 100 / 255.0f, 149 / 255.0f, 237 / 255.0f, 1f }); //GL.Fog(FogParameter.FogDensity,0.1f); GL.Fog(FogParameter.FogMode, (int)FogMode.Linear); GL.Fog(FogParameter.FogStart, (float)4000); GL.Fog(FogParameter.FogEnd, (float)size); GL.Disable(EnableCap.DepthTest); GL.DepthFunc(DepthFunction.Always); /* * GL.Begin(BeginMode.LineStrip); * * GL.Color3(Color.White); * GL.Vertex3(0, 0, 0); * * GL.Color3(Color.Red); * GL.Vertex3(area.Bottom, 0, area.Left); * * GL.Color3(Color.Yellow); * GL.Vertex3(lookX, lookY, lookZ); * * GL.Color3(Color.Green); * GL.Vertex3(cameraX, cameraY, cameraZ); * * GL.End(); */ /* * GL.PointSize(10); * GL.Color4(Color.Yellow); * GL.LineWidth(5); * * * GL.Begin(PrimitiveType.LineStrip); * * GL.Vertex3(area.LocationTopLeft.Lng, area.LocationTopLeft.Lat, (float)cameraZ); * GL.Vertex3(area.LocationTopLeft.Lng, area.LocationRightBottom.Lat, (float)cameraZ); * GL.Vertex3(area.LocationRightBottom.Lng, area.LocationRightBottom.Lat, (float)cameraZ); * GL.Vertex3(area.LocationRightBottom.Lng, area.LocationTopLeft.Lat, (float)cameraZ); * GL.Vertex3(area.LocationTopLeft.Lng, area.LocationTopLeft.Lat, (float)cameraZ); * * GL.End(); * * GL.PointSize((float) (step*1)); * GL.Color3(Color.Blue); * GL.Begin(PrimitiveType.Points); * GL.Vertex3(new Vector3((float) center.Lng, (float) center.Lat, (float) cameraZ)); * GL.End(); */ //GL.ClampColor(ClampColorTarget.ClampReadColor, ClampColorMode.True); /* * GL.Enable(EnableCap.Blend); * GL.DepthMask(false); * GL.BlendFunc(BlendingFactorSrc.Zero, BlendingFactorDest.Src1Color); * GL.DepthMask(true); * GL.Disable(EnableCap.Blend); */ // textureid.Clear(); core.fillEmptyTiles = true; core.LevelsKeepInMemmory = 20; core.Provider = type; core.Position = center; //core.ReloadMap(); List <tileZoomArea> tileArea = new List <tileZoomArea>(); for (int a = 10; a <= zoom; a++) { core.Zoom = a; var area2 = new RectLatLng(center.Lat, center.Lng, 0, 0); // 200m at max zoom // step at 0 zoom var distm = MathHelper.map(a, 0, zoom, size, 50); var offset = center.newpos(rpy.Z, distm); area2.Inflate(Math.Abs(center.Lat - offset.Lat), Math.Abs(center.Lng - offset.Lng)); var extratile = 0; if (a == zoom) { extratile = 1; } var tiles = new tileZoomArea() { zoom = a, points = prj.GetAreaTileList(area2, a, extratile), area = area2 }; tileArea.Add(tiles); } //tileArea.Reverse(); while (textureid.Count > 250) { var first = textureid.Keys.First(); GL.DeleteTexture(textureid[first]); textureid.Remove(first); } // get tiles & combine into one foreach (var tilearea in tileArea) { foreach (var p in tilearea.points) { core.tileDrawingListLock.AcquireReaderLock(); core.Matrix.EnterReadLock(); try { GMap.NET.Internals.Tile t = core.Matrix.GetTileWithNoLock(tilearea.zoom, p); if (t.NotEmpty) { foreach (GMapImage img in t.Overlays) { if (img.IsParent) { } if (!textureid.ContainsKey(p)) { try { generateTexture(p, (Bitmap)img.Img); } catch { continue; } } } } else { } } finally { core.Matrix.LeaveReadLock(); core.tileDrawingListLock.ReleaseReaderLock(); } if (textureid.ContainsKey(p)) { int texture = textureid[p]; GL.Enable(EnableCap.Texture2D); GL.BindTexture(TextureTarget.Texture2D, texture); } else { //Console.WriteLine("Missing tile"); GL.Disable(EnableCap.Texture2D); continue; } long xr = p.X * prj.TileSize.Width; long yr = p.Y * prj.TileSize.Width; long x2 = (p.X + 1) * prj.TileSize.Width; long y2 = (p.Y + 1) * prj.TileSize.Width; GL.LineWidth(4); GL.Color3(Color.White); GL.Clear(ClearBufferMask.DepthBufferBit); GL.Enable(EnableCap.DepthTest); // generate terrain GL.Begin(PrimitiveType.Points); GL.PointSize((float)(20)); //GL.Begin(PrimitiveType.Points); GL.Color3(Color.Blue); var latlng = prj.FromPixelToLatLng(xr, yr, tilearea.zoom); var utm = convertCoords(latlng); utm[2] = srtm.getAltitude(latlng.Lat, latlng.Lng).alt; GL.TexCoord2(0, 0); GL.Vertex3(utm[0], utm[1], utm[2]); // next down latlng = prj.FromPixelToLatLng(xr, y2, tilearea.zoom); utm = convertCoords(latlng); utm[2] = srtm.getAltitude(latlng.Lat, latlng.Lng).alt; GL.TexCoord2(0, 1); GL.Vertex3(utm[0], utm[1], utm[2]); // next right latlng = prj.FromPixelToLatLng(x2, yr, tilearea.zoom); utm = convertCoords(latlng); utm[2] = srtm.getAltitude(latlng.Lat, latlng.Lng).alt; GL.TexCoord2(1, 0); GL.Vertex3(utm[0], utm[1], utm[2]); // next right down latlng = prj.FromPixelToLatLng(x2, y2, tilearea.zoom); utm = convertCoords(latlng); utm[2] = srtm.getAltitude(latlng.Lat, latlng.Lng).alt; GL.TexCoord2(1, 1); GL.Vertex3(utm[0], utm[1], utm[2]); GL.End(); var dist = LocationCenter.GetDistance(latlng); var pxstep = 128; if (dist < 500) { pxstep = 32; } double[] oldutm = null; GL.Begin(PrimitiveType.TriangleStrip); for (long x = xr; x < x2; x += pxstep) { long xnext = x + pxstep; //GL.Begin(PrimitiveType.LineStrip); for (long y = yr; y < y2; y += pxstep) { long ynext = y + pxstep; //GL.Begin(PrimitiveType.Lines); var latlng1 = prj.FromPixelToLatLng(x, y, tilearea.zoom); var utm1 = convertCoords(latlng1); utm1[2] = srtm.getAltitude(latlng1.Lat, latlng1.Lng).alt; var imgx = MathHelper.map(x, xr, x2, 0, 1); var imgy = MathHelper.map(y, yr, y2, 0, 1); GL.TexCoord2(imgx, imgy); GL.Vertex3(utm1[0], utm1[1], utm1[2]); // var latlng2 = prj.FromPixelToLatLng(x, ynext, tilearea.zoom); var utm2 = convertCoords(latlng2); utm2[2] = srtm.getAltitude(latlng2.Lat, latlng2.Lng).alt; imgx = MathHelper.map(x, xr, x2, 0, 1); imgy = MathHelper.map(ynext, yr, y2, 0, 1); GL.TexCoord2(imgx, imgy); GL.Vertex3(utm2[0], utm2[1], utm2[2]); // latlng2 = prj.FromPixelToLatLng(xnext, y, tilearea.zoom); utm2 = convertCoords(latlng2); utm2[2] = srtm.getAltitude(latlng2.Lat, latlng2.Lng).alt; imgx = MathHelper.map(xnext, xr, x2, 0, 1); imgy = MathHelper.map(y, yr, y2, 0, 1); GL.TexCoord2(imgx, imgy); GL.Vertex3(utm2[0], utm2[1], utm2[2]); // latlng2 = prj.FromPixelToLatLng(xnext, ynext, tilearea.zoom); utm2 = convertCoords(latlng2); utm2[2] = srtm.getAltitude(latlng2.Lat, latlng2.Lng).alt; imgx = MathHelper.map(xnext, xr, x2, 0, 1); imgy = MathHelper.map(ynext, yr, y2, 0, 1); GL.TexCoord2(imgx, imgy); GL.Vertex3(utm2[0], utm2[1], utm2[2]); } } GL.End(); GL.Disable(EnableCap.Texture2D); } } GL.Flush(); try { this.SwapBuffers(); Context.MakeCurrent(null); } catch { } //this.Invalidate(); var delta = DateTime.Now - start; Console.WriteLine("OpenGLTest2 {0}", delta.TotalMilliseconds); }
private void generateTextures() { core.fillEmptyTiles = false; core.LevelsKeepInMemmory = 10; core.Provider = type; //core.ReloadMap(); List <tileZoomArea> tileArea = new List <tileZoomArea>(); //if (center.GetDistance(oldcenter) > 30) { oldcenter = new PointLatLngAlt(center); zoom = 18; for (int a = 12; a <= zoom; a++) { var area2 = new RectLatLng(center.Lat, center.Lng, 0, 0); // 200m at max zoom // step at 0 zoom var distm = MathHelper.map(a, 0, zoom, 3000, 10); //Console.WriteLine("tiles z {0} max {1} dist {2}", a, zoom, distm); var offset = center.newpos(rpy.Z, distm); area2.Inflate(Math.Abs(center.Lat - offset.Lat), Math.Abs(center.Lng - offset.Lng)); var extratile = 0; if (a == zoom) { extratile = 1; } var tiles = new tileZoomArea() { zoom = a, points = prj.GetAreaTileList(area2, a, extratile), area = area2 }; tileArea.Add(tiles); } } var totaltiles = tileArea.Sum(a => a.points.Count); Console.WriteLine(DateTime.Now.Millisecond + " Total tiles " + totaltiles); textureid.Where(a => !tileArea.Any(b => b.points.Contains(a.Key))).ForEach(c => { this.BeginInvoke((MethodInvoker) delegate { Console.WriteLine(DateTime.Now.Millisecond + " tile cleanup"); tileInfo temp; textureid.TryRemove(c.Key, out temp); temp?.Cleanup(); }); }); //https://wiki.openstreetmap.org/wiki/Zoom_levels var C = 2 * Math.PI * 6378137.000; // horizontal distance by each tile square var stile = C * Math.Cos(center.Lat) / Math.Pow(2, zoom); var pxstep = 2; // get tiles & combine into one foreach (var tilearea in tileArea) { stile = C * Math.Cos(center.Lat) / Math.Pow(2, tilearea.zoom); if (tilearea.zoom == 20) { pxstep = 256; } if (tilearea.zoom == 19) { pxstep = 128; } if (tilearea.zoom == 18) { pxstep = 64; } if (tilearea.zoom == 17) { pxstep = 32; } if (tilearea.zoom == 16) { pxstep = 16; } if (tilearea.zoom == 15) { pxstep = 8; } if (tilearea.zoom == 14) { pxstep = 4; } if (tilearea.zoom == 13) { pxstep = 2; } if (tilearea.zoom == 12) { pxstep = 1; } foreach (var p in tilearea.points) { core.tileDrawingListLock.AcquireReaderLock(); core.Matrix.EnterReadLock(); long xr = p.X * prj.TileSize.Width; long yr = p.Y * prj.TileSize.Width; long x2 = (p.X + 1) * prj.TileSize.Width; long y2 = (p.Y + 1) * prj.TileSize.Width; try { GMap.NET.Internals.Tile t = core.Matrix.GetTileWithNoLock(tilearea.zoom, p); if (t.NotEmpty) { foreach (GMapImage img in t.Overlays) { if (!textureid.ContainsKey(p)) { try { var ti = new tileInfo() { point = p, zoom = tilearea.zoom, img = (Image)img.Img.Clone() }; for (long x = xr; x < x2; x += pxstep) { long xnext = x + pxstep; for (long y = yr; y < y2; y += pxstep) { long ynext = y + pxstep; var latlng1 = prj.FromPixelToLatLng(x, y, tilearea.zoom); if (srtm.getAltitude(latlng1.Lat, latlng1.Lng).currenttype == srtm.tiletype.invalid) { ti = null; x = x2; y = y2; break; } var utm1 = convertCoords(latlng1); utm1[2] = srtm.getAltitude(latlng1.Lat, latlng1.Lng).alt; var imgx = MathHelper.map(x, xr, x2, 0, 1); var imgy = MathHelper.map(y, yr, y2, 0, 1); ti.texture.Add(new tileInfo.TextureCoords((float)imgx, (float)imgy)); ti.vertex.Add(new tileInfo.Vertex((float)utm1[0], (float)utm1[1], (float)utm1[2])); // var latlng2 = prj.FromPixelToLatLng(x, ynext, tilearea.zoom); var utm2 = convertCoords(latlng2); utm2[2] = srtm.getAltitude(latlng2.Lat, latlng2.Lng).alt; imgx = MathHelper.map(x, xr, x2, 0, 1); imgy = MathHelper.map(ynext, yr, y2, 0, 1); ti.texture.Add(new tileInfo.TextureCoords((float)imgx, (float)imgy)); ti.vertex.Add(new tileInfo.Vertex((float)utm2[0], (float)utm2[1], (float)utm2[2])); // latlng2 = prj.FromPixelToLatLng(xnext, y, tilearea.zoom); utm2 = convertCoords(latlng2); utm2[2] = srtm.getAltitude(latlng2.Lat, latlng2.Lng).alt; imgx = MathHelper.map(xnext, xr, x2, 0, 1); imgy = MathHelper.map(y, yr, y2, 0, 1); ti.texture.Add(new tileInfo.TextureCoords((float)imgx, (float)imgy)); ti.vertex.Add(new tileInfo.Vertex((float)utm2[0], (float)utm2[1], (float)utm2[2])); // latlng2 = prj.FromPixelToLatLng(xnext, ynext, tilearea.zoom); utm2 = convertCoords(latlng2); utm2[2] = srtm.getAltitude(latlng2.Lat, latlng2.Lng).alt; imgx = MathHelper.map(xnext, xr, x2, 0, 1); imgy = MathHelper.map(ynext, yr, y2, 0, 1); ti.texture.Add(new tileInfo.TextureCoords((float)imgx, (float)imgy)); ti.vertex.Add(new tileInfo.Vertex((float)utm2[0], (float)utm2[1], (float)utm2[2])); } } if (ti != null) { textureid[p] = ti; } } catch { continue; } } } } } finally { core.Matrix.LeaveReadLock(); core.tileDrawingListLock.ReleaseReaderLock(); } } } }
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { if (this.DesignMode) { return; } if (area.LocationMiddle.Lat == 0 && area.LocationMiddle.Lng == 0) { return; } try { base.OnPaint(e); } catch { return; } double heightscale = (step / 90.0) * 1; float yawradians = (float)(Math.PI * (rpy.Z * 1) / 180.0f); //radians = 0; float mouseY = (float)step / 10f; cameraX = center.Lng; // -Math.Sin(yawradians) * mouseY; // multiplying by mouseY makes the cameraY = center.Lat; // -Math.Cos(yawradians) * mouseY; // camera get closer/farther away with mouseY cameraZ = (center.Alt < srtm.getAltitude(center.Lat, center.Lng).alt) ? (srtm.getAltitude(center.Lat, center.Lng).alt + 1) * heightscale : center.Alt * heightscale; // (srtm.getAltitude(lookZ, lookX, 20) + 100) * heighscale; lookX = center.Lng + Math.Sin(yawradians) * mouseY; lookY = center.Lat + Math.Cos(yawradians) * mouseY; lookZ = cameraZ; // cameraZ += 0.04; GMapProvider type = GMap.NET.MapProviders.GoogleSatelliteMapProvider.Instance; PureProjection prj = type.Projection; int size = (int)(cameraZ * 150000); // in front PointLatLngAlt leftf = center.newpos(rpy.Z, size); // behind PointLatLngAlt rightf = center.newpos(rpy.Z, 50); // left : 90 allows for 180 degree viewing angle PointLatLngAlt left = center.newpos(rpy.Z - 90, size); // right PointLatLngAlt right = center.newpos(rpy.Z + 90, size); double maxlat = Math.Max(left.Lat, Math.Max(right.Lat, Math.Max(leftf.Lat, rightf.Lat))); double minlat = Math.Min(left.Lat, Math.Min(right.Lat, Math.Min(leftf.Lat, rightf.Lat))); double maxlng = Math.Max(left.Lng, Math.Max(right.Lng, Math.Max(leftf.Lng, rightf.Lng))); double minlng = Math.Min(left.Lng, Math.Min(right.Lng, Math.Min(leftf.Lng, rightf.Lng))); // if (Math.Abs(area.Lat - maxlat) < 0.001) { } // else { area = RectLatLng.FromLTRB(minlng, maxlat, maxlng, minlat); } GPoint topLeftPx = prj.FromLatLngToPixel(area.LocationTopLeft, zoom); GPoint rightButtomPx = prj.FromLatLngToPixel(area.Bottom, area.Right, zoom); GPoint pxDelta = new GPoint(rightButtomPx.X - topLeftPx.X, rightButtomPx.Y - topLeftPx.Y); zoom = 21; pxDelta.X = 9999; int otherzoomlevel = 12; // zoom based on pixel density while (pxDelta.X > this.Width) { zoom--; // current area topLeftPx = prj.FromLatLngToPixel(area.LocationTopLeft, zoom); rightButtomPx = prj.FromLatLngToPixel(area.Bottom, area.Right, zoom); pxDelta = new GPoint(rightButtomPx.X - topLeftPx.X, rightButtomPx.Y - topLeftPx.Y); } otherzoomlevel = zoom - 4; Console.WriteLine("zoom {0}", zoom); // update once per seconds - we only read from disk, so need to let cahce settle if (lastrefresh.AddSeconds(0.5) < DateTime.Now) { // get tiles - bg core.Provider = type; core.Position = LocationCenter; // get zoom 10 core.Zoom = otherzoomlevel; core.OnMapSizeChanged(this.Width, this.Height); // get actual current zoom core.Zoom = zoom; core.OnMapSizeChanged(this.Width, this.Height); lastrefresh = DateTime.Now; } else { //return; } float screenscale = this.Width / (float)this.Height; MakeCurrent(); GL.MatrixMode(MatrixMode.Projection); OpenTK.Matrix4 projection = OpenTK.Matrix4.CreatePerspectiveFieldOfView(120 * deg2rad, screenscale, 0.00001f, (float)step * 20000); GL.LoadMatrix(ref projection); Matrix4 modelview = Matrix4.LookAt((float)cameraX, (float)cameraY, (float)cameraZ, (float)lookX, (float)lookY, (float)lookZ, 0, 0, 1); GL.MatrixMode(MatrixMode.Modelview); // roll modelview = Matrix4.Mult(modelview, Matrix4.CreateRotationZ(rpy.X * deg2rad)); // pitch modelview = Matrix4.Mult(modelview, Matrix4.CreateRotationX((rpy.Y - 15) * -deg2rad)); GL.LoadMatrix(ref modelview); GL.ClearColor(Color.CornflowerBlue); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.AccumBufferBit); GL.LightModel(LightModelParameter.LightModelAmbient, new float[] { 1f, 1f, 1f, 1f }); // GL.Disable(EnableCap.Fog); GL.Enable(EnableCap.Fog); //GL.Enable(EnableCap.Lighting); //GL.Enable(EnableCap.Light0); GL.Fog(FogParameter.FogColor, new float[] { 100 / 255.0f, 149 / 255.0f, 237 / 255.0f, 1f }); //GL.Fog(FogParameter.FogDensity,0.1f); GL.Fog(FogParameter.FogMode, (int)FogMode.Linear); GL.Fog(FogParameter.FogStart, (float)step * 40); GL.Fog(FogParameter.FogEnd, (float)(step * 50)); // GL.Enable(EnableCap.DepthTest); GL.DepthFunc(DepthFunction.Always); /* * GL.Begin(BeginMode.LineStrip); * * GL.Color3(Color.White); * GL.Vertex3(0, 0, 0); * * //GL.Color3(Color.Red); * GL.Vertex3(area.Bottom, 0, area.Left); * * //GL.Color3(Color.Yellow); * GL.Vertex3(lookX, lookY, lookZ); * * //GL.Color3(Color.Green); * GL.Vertex3(cameraX, cameraY, cameraZ); * * GL.End(); */ /* * GL.PointSize(10); * GL.Color4(Color.Yellow); * GL.LineWidth(5); * * * GL.Begin(PrimitiveType.LineStrip); * * //GL.Vertex3(new Vector3((float)center.Lng,(float)center.Lat,(float)(center.Alt * heightscale))); * //GL.Vertex3(new Vector3(0, 0, 0)); * //GL.Vertex3(new Vector3((float)cameraX, (float)cameraY, (float)cameraZ)); * //GL.Color3(Color.Green); * //GL.Vertex3(new Vector3((float)lookX, (float)lookY, (float)lookZ)); * * GL.Vertex3(area.LocationTopLeft.Lng, area.LocationTopLeft.Lat, (float)cameraZ); * GL.Vertex3(area.LocationTopLeft.Lng, area.LocationRightBottom.Lat, (float)cameraZ); * GL.Vertex3(area.LocationRightBottom.Lng, area.LocationRightBottom.Lat, (float)cameraZ); * GL.Vertex3(area.LocationRightBottom.Lng, area.LocationTopLeft.Lat, (float)cameraZ); * GL.Vertex3(area.LocationTopLeft.Lng, area.LocationTopLeft.Lat, (float)cameraZ); * * GL.End(); */ GL.Finish(); GL.PointSize((float)(step * 1)); GL.Color3(Color.Blue); GL.Begin(PrimitiveType.Points); GL.Vertex3(new Vector3((float)center.Lng, (float)center.Lat, (float)cameraZ)); GL.End(); //GL.ClampColor(ClampColorTarget.ClampReadColor, ClampColorMode.True); /* * GL.Enable(EnableCap.Blend); * GL.DepthMask(false); * GL.BlendFunc(BlendingFactorSrc.Zero, BlendingFactorDest.Src1Color); * GL.DepthMask(true); * GL.Disable(EnableCap.Blend); */ // textureid.Clear(); // get level 10 tiles List <GPoint> tileArea1 = prj.GetAreaTileList(area, otherzoomlevel, 1); // get type list at new zoom level List <GPoint> tileArea2 = prj.GetAreaTileList(area, zoom, 2); List <GPoint> tileArea = new List <GPoint>(); tileArea.AddRange(tileArea1); tileArea.AddRange(tileArea2); // get tiles & combine into one foreach (var p in tileArea) { int localzoom = zoom; core.tileDrawingListLock.AcquireReaderLock(); core.Matrix.EnterReadLock(); try { if (tileArea1.Contains(p)) { localzoom = otherzoomlevel; } topLeftPx = prj.FromLatLngToPixel(area.LocationTopLeft, localzoom); GMap.NET.Internals.Tile t = core.Matrix.GetTileWithNoLock(localzoom, p); if (t.NotEmpty) { foreach (GMapImage img in t.Overlays) { if (!textureid.ContainsKey(p)) { generateTexture(p, (Bitmap)img.Img); } } } else { } } finally { core.Matrix.LeaveReadLock(); core.tileDrawingListLock.ReleaseReaderLock(); } //GMapImage tile = ((PureImageCache)Maps.MyImageCache.Instance).GetImageFromCache(type.DbId, p, zoom) as GMapImage; //if (tile != null && !textureid.ContainsKey(p)) { // generateTexture(p, (Bitmap)tile.Img); } if (textureid.ContainsKey(p)) { int texture = textureid[p]; GL.Enable(EnableCap.Texture2D); GL.BindTexture(TextureTarget.Texture2D, texture); } else { //Console.WriteLine("Missing tile"); continue; } long x = p.X * prj.TileSize.Width - topLeftPx.X; long y = p.Y * prj.TileSize.Width - topLeftPx.Y; long xr = p.X * prj.TileSize.Width; long yr = p.Y * prj.TileSize.Width; long x2 = (p.X + 1) * prj.TileSize.Width; long y2 = (p.Y + 1) * prj.TileSize.Width; GL.LineWidth(0); GL.Color3(Color.White); // generate terrain GL.Begin(PrimitiveType.TriangleStrip); var latlng = prj.FromPixelToLatLng(xr, yr, localzoom); double heightl = srtm.getAltitude(latlng.Lat, latlng.Lng).alt; if (localzoom == 10) { heightl = 0; } //xr - topLeftPx.X, yr - topLeftPx.Y GL.TexCoord2(0, 0); GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale); // next down latlng = prj.FromPixelToLatLng(xr, y2, localzoom); heightl = srtm.getAltitude(latlng.Lat, latlng.Lng).alt; if (localzoom == 10) { heightl = 0; } GL.TexCoord2(0, 1); GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale); // next right latlng = prj.FromPixelToLatLng(x2, yr, localzoom); heightl = srtm.getAltitude(latlng.Lat, latlng.Lng).alt; if (localzoom == 10) { heightl = 0; } GL.TexCoord2(1, 0); GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale); // next right down latlng = prj.FromPixelToLatLng(x2, y2, localzoom); heightl = srtm.getAltitude(latlng.Lat, latlng.Lng).alt; if (localzoom == 10) { heightl = 0; } GL.TexCoord2(1, 1); GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale); GL.End(); } GL.Flush(); try { this.SwapBuffers(); Context.MakeCurrent(null); } catch { } //this.Invalidate(); return; }
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { if (this.DesignMode) { return; } if (area.LocationMiddle.Lat == 0 && area.LocationMiddle.Lng == 0) { return; } try { base.OnPaint(e); } catch { return; } double heightscale = (step / 90.0) * 3; float yawradians = (float)(Math.PI * (rpy.Z * 1) / 180.0f); //radians = 0; float mouseY = (float)(0.0025); cameraX = area.LocationMiddle.Lng; // -Math.Sin(yawradians) * mouseY; // multiplying by mouseY makes the cameraY = area.LocationMiddle.Lat; // -Math.Cos(yawradians) * mouseY; // camera get closer/farther away with mouseY cameraZ = (LocationCenter.Alt < srtm.getAltitude(center.Lat, center.Lng)) ? (srtm.getAltitude(center.Lat, center.Lng) + 1) * heightscale : LocationCenter.Alt * heightscale; // (srtm.getAltitude(lookZ, lookX, 20) + 100) * heighscale; lookX = area.LocationMiddle.Lng + Math.Sin(yawradians) * mouseY; lookY = area.LocationMiddle.Lat + Math.Cos(yawradians) * mouseY; lookZ = cameraZ; // cameraZ += 0.04; GMapProvider type = GMap.NET.MapProviders.GoogleSatelliteMapProvider.Instance; PureProjection prj = type.Projection; PointLatLngAlt leftf = center.newpos(rpy.Z, 500); PointLatLngAlt rightf = center.newpos(rpy.Z, 10); PointLatLngAlt left = center.newpos(rpy.Z - 90, 500); PointLatLngAlt right = center.newpos(rpy.Z + 90, 500); double maxlat = Math.Max(left.Lat, Math.Max(right.Lat, Math.Max(leftf.Lat, rightf.Lat))); double minlat = Math.Min(left.Lat, Math.Min(right.Lat, Math.Min(leftf.Lat, rightf.Lat))); double maxlng = Math.Max(left.Lng, Math.Max(right.Lng, Math.Max(leftf.Lng, rightf.Lng))); double minlng = Math.Min(left.Lng, Math.Min(right.Lng, Math.Min(leftf.Lng, rightf.Lng))); area = RectLatLng.FromLTRB(minlng, maxlat, maxlng, minlat); GPoint topLeftPx = prj.FromLatLngToPixel(area.LocationTopLeft, zoom); GPoint rightButtomPx = prj.FromLatLngToPixel(area.Bottom, area.Right, zoom); GPoint pxDelta = new GPoint(rightButtomPx.X - topLeftPx.X, rightButtomPx.Y - topLeftPx.Y); zoom = 17; // zoom based on pixel density while (pxDelta.X > 2000) { zoom--; // current area topLeftPx = prj.FromLatLngToPixel(area.LocationTopLeft, zoom); rightButtomPx = prj.FromLatLngToPixel(area.Bottom, area.Right, zoom); pxDelta = new GPoint(rightButtomPx.X - topLeftPx.X, rightButtomPx.Y - topLeftPx.Y); } // update once per seconds - we only read from disk, so need to let cahce settle if (lastrefresh.AddSeconds(.6) < DateTime.Now) { // get tiles - bg core.Provider = type; core.Position = LocationCenter; core.Zoom = zoom; core.OnMapSizeChanged(this.Width, this.Height); lastrefresh = DateTime.Now; } else { //return; } MakeCurrent(); GL.MatrixMode(MatrixMode.Projection); OpenTK.Matrix4 projection = OpenTK.Matrix4.CreatePerspectiveFieldOfView(130 * deg2rad, 1f, 0.00001f, (float)step * 100); GL.LoadMatrix(ref projection); Matrix4 modelview = Matrix4.LookAt((float)cameraX, (float)cameraY, (float)cameraZ, (float)lookX, (float)lookY, (float)lookZ, 0, 0, 1); GL.MatrixMode(MatrixMode.Modelview); // roll modelview = Matrix4.Mult(modelview, Matrix4.CreateRotationZ(rpy.X * deg2rad)); // pitch modelview = Matrix4.Mult(modelview, Matrix4.CreateRotationX((rpy.Y - 10) * -deg2rad)); GL.LoadMatrix(ref modelview); GL.ClearColor(Color.LightBlue); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.LightModel(LightModelParameter.LightModelAmbient, new float[] { 1f, 1f, 1f, 1f }); GL.Enable(EnableCap.Fog); // GL.Enable(EnableCap.Lighting); // GL.Enable(EnableCap.Light0); GL.Fog(FogParameter.FogColor, new float[] { 0.5f, 0.5f, 0.5f, 1f }); //GL.Fog(FogParameter.FogDensity,0.1f); GL.Fog(FogParameter.FogMode, (int)FogMode.Linear); GL.Fog(FogParameter.FogStart, (float)step * 1); GL.Fog(FogParameter.FogEnd, (float)(step * 7)); /* * GL.Begin(BeginMode.LineStrip); * * GL.Color3(Color.White); * GL.Vertex3(0, 0, 0); * * GL.Vertex3(area.Bottom, 0, area.Left); * * GL.Vertex3(lookX, lookY, lookZ); * * //GL.Vertex3(cameraX, cameraY, cameraZ); * * GL.End(); */ GL.Begin(PrimitiveType.LineStrip); GL.PointSize(200); GL.Color3(Color.Red); //GL.Vertex3(new Vector3((float)center.Lng,(float)center.Lat,(float)(center.Alt * heightscale))); //GL.Vertex3(new Vector3(0, 0, 0)); //GL.Vertex3(new Vector3((float)cameraX, (float)cameraY, (float)cameraZ)); //GL.Color3(Color.Green); //GL.Vertex3(new Vector3((float)lookX, (float)lookY, (float)lookZ)); GL.Vertex3(area.LocationTopLeft.Lng, area.LocationTopLeft.Lat, 0); GL.Vertex3(area.LocationTopLeft.Lng, area.LocationRightBottom.Lat, 0); GL.Vertex3(area.LocationRightBottom.Lng, area.LocationRightBottom.Lat, 0); GL.Vertex3(area.LocationRightBottom.Lng, area.LocationTopLeft.Lat, 0); GL.Vertex3(area.LocationTopLeft.Lng, area.LocationTopLeft.Lat, 0); GL.End(); GL.Begin(PrimitiveType.LineStrip); GL.PointSize(200); GL.Color3(Color.Red); GL.Vertex3(new Vector3((float)center.Lng, (float)center.Lat, 0)); GL.Vertex3(new Vector3((float)leftf.Lng, (float)leftf.Lat, 0)); GL.End(); GL.Begin(PrimitiveType.Points); GL.PointSize(100); GL.Color3(Color.Blue); GL.Vertex3(new Vector3((float)center.Lng, (float)center.Lat, 0)); GL.End(); //textureid.Clear(); // get type list at new zoom level List <GPoint> tileArea = prj.GetAreaTileList(area, zoom, 0); // get tiles & combine into one foreach (var p in tileArea) { core.tileDrawingListLock.AcquireReaderLock(); core.Matrix.EnterReadLock(); try { GMap.NET.Internals.Tile t = core.Matrix.GetTileWithNoLock(core.Zoom, p); if (t.NotEmpty) { foreach (GMapImage img in t.Overlays) { if (!textureid.ContainsKey(p)) { generateTexture(p, (Bitmap)img.Img); } } } else { } } finally { core.Matrix.LeaveReadLock(); core.tileDrawingListLock.ReleaseReaderLock(); } //GMapImage tile = ((PureImageCache)Maps.MyImageCache.Instance).GetImageFromCache(type.DbId, p, zoom) as GMapImage; //if (tile != null && !textureid.ContainsKey(p)) { // generateTexture(p, (Bitmap)tile.Img); } if (textureid.ContainsKey(p)) { int texture = textureid[p]; GL.Enable(EnableCap.Texture2D); GL.BindTexture(TextureTarget.Texture2D, texture); } else { GL.Disable(EnableCap.Texture2D); } long x = p.X * prj.TileSize.Width - topLeftPx.X; long y = p.Y * prj.TileSize.Width - topLeftPx.Y; long xr = p.X * prj.TileSize.Width; long yr = p.Y * prj.TileSize.Width; long x2 = (p.X + 1) * prj.TileSize.Width; long y2 = (p.Y + 1) * prj.TileSize.Width; // generate terrain GL.Begin(PrimitiveType.TriangleStrip); var latlng = prj.FromPixelToLatLng(xr, yr, zoom); double heightl = srtm.getAltitude(latlng.Lat, latlng.Lng); GL.Color3(Color.White); //xr - topLeftPx.X, yr - topLeftPx.Y GL.TexCoord2(0, 0); GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale); // next down latlng = prj.FromPixelToLatLng(xr, y2, zoom); heightl = srtm.getAltitude(latlng.Lat, latlng.Lng); GL.TexCoord2(0, .99); GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale); // next right latlng = prj.FromPixelToLatLng(x2, yr, zoom); heightl = srtm.getAltitude(latlng.Lat, latlng.Lng); GL.TexCoord2(.99, 0); GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale); // next right down latlng = prj.FromPixelToLatLng(x2, y2, zoom); heightl = srtm.getAltitude(latlng.Lat, latlng.Lng); GL.TexCoord2(.99, .99); GL.Vertex3(latlng.Lng, latlng.Lat, heightl * heightscale); GL.End(); } GL.Enable(EnableCap.Blend); GL.DepthMask(false); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One); GL.DepthMask(true); GL.Disable(EnableCap.Blend); GL.Flush(); try { this.SwapBuffers(); Context.MakeCurrent(null); } catch { } return; }