You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
381 lines
13 KiB
381 lines
13 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using System.Text; |
|
using OpenTK; |
|
using OpenTK.Graphics.OpenGL; |
|
using System.Drawing.Imaging; |
|
using System.Drawing; |
|
using GMap.NET; |
|
using GMap.NET.WindowsForms; |
|
|
|
namespace ArdupilotMega.Controls |
|
{ |
|
public class OpenGLtest : GLControl |
|
{ |
|
public static OpenGLtest instance; |
|
|
|
// terrain image |
|
Bitmap _terrain = new Bitmap(640,480); |
|
int texture = 0; |
|
|
|
float _angle = 0; |
|
double cameraX, cameraY, cameraZ; // camera coordinates |
|
double lookX, lookY, lookZ; // camera look-at coordinates |
|
|
|
double step = 1 / 1200.0; |
|
|
|
// image zoom level |
|
int zoom = 11; |
|
|
|
RectLatLng area = new RectLatLng(-35.04286,117.84262,0.1,0.1); |
|
|
|
double _alt = 0; |
|
public PointLatLngAlt LocationCenter { |
|
get { |
|
return new PointLatLngAlt(area.LocationMiddle.Lat, area.LocationMiddle.Lng,_alt,""); |
|
} |
|
set { |
|
|
|
if (area.LocationMiddle.Lat == value.Lat && area.LocationMiddle.Lng == value.Lng) |
|
return; |
|
|
|
if (value.Lat == 0 && value.Lng == 0) |
|
return; |
|
|
|
_alt = value.Alt; |
|
area = new RectLatLng(value.Lat + 0.15, value.Lng - 0.15, 0.3, 0.3); |
|
// Console.WriteLine(area.LocationMiddle + " " + value.ToString()); |
|
this.Invalidate(); |
|
} |
|
} |
|
|
|
public Vector3 rpy = new Vector3(); |
|
|
|
public OpenGLtest() |
|
{ |
|
instance = this; |
|
|
|
InitializeComponent(); |
|
|
|
GL.GenTextures(1, out texture); |
|
} |
|
|
|
void getImage() |
|
{ |
|
MapType type = MapType.GoogleSatellite; |
|
PureProjection prj = null; |
|
int maxZoom; |
|
|
|
GMaps.Instance.AdjustProjection(type, ref prj, out maxZoom); |
|
//int zoom = 14; // 12 |
|
if (!area.IsEmpty) |
|
{ |
|
try |
|
{ |
|
List<GPoint> tileArea = prj.GetAreaTileList(area, zoom, 0); |
|
//string bigImage = zoom + "-" + type + "-vilnius.png"; |
|
|
|
//Console.WriteLine("Preparing: " + bigImage); |
|
//Console.WriteLine("Zoom: " + zoom); |
|
//Console.WriteLine("Type: " + type.ToString()); |
|
//Console.WriteLine("Area: " + area); |
|
|
|
var types = GMaps.Instance.GetAllLayersOfType(type); |
|
|
|
// current area |
|
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); |
|
|
|
DateTime startimage = DateTime.Now; |
|
|
|
int padding = 0; |
|
{ |
|
using (Bitmap bmpDestination = new Bitmap(pxDelta.X + padding * 2, pxDelta.Y + padding * 2)) |
|
{ |
|
using (Graphics gfx = Graphics.FromImage(bmpDestination)) |
|
{ |
|
gfx.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver; |
|
|
|
// get tiles & combine into one |
|
foreach (var p in tileArea) |
|
{ |
|
Console.WriteLine("Downloading[" + p + "]: " + tileArea.IndexOf(p) + " of " + tileArea.Count); |
|
|
|
foreach (MapType tp in types) |
|
{ |
|
Exception ex; |
|
WindowsFormsImage tile = GMaps.Instance.GetImageFrom(tp, p, zoom, out ex) as WindowsFormsImage; |
|
if (tile != null) |
|
{ |
|
using (tile) |
|
{ |
|
int x = p.X * prj.TileSize.Width - topLeftPx.X + padding; |
|
int y = p.Y * prj.TileSize.Width - topLeftPx.Y + padding; |
|
{ |
|
gfx.DrawImage(tile.Img, x, y, prj.TileSize.Width, prj.TileSize.Height); |
|
} |
|
} |
|
} |
|
} |
|
if ((DateTime.Now - startimage).TotalMilliseconds > 200) |
|
break; |
|
} |
|
} |
|
_terrain = new Bitmap(bmpDestination, 512, 512); |
|
|
|
|
|
GL.BindTexture(TextureTarget.Texture2D, texture); |
|
|
|
BitmapData data = _terrain.LockBits(new System.Drawing.Rectangle(0, 0, _terrain.Width, _terrain.Height), |
|
ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); |
|
|
|
//Console.WriteLine("w {0} h {1}",data.Width, data.Height); |
|
|
|
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0, |
|
OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0); |
|
|
|
_terrain.UnlockBits(data); |
|
|
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); |
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); |
|
|
|
|
|
} |
|
} |
|
if ((DateTime.Now - startimage).TotalMilliseconds > 200) |
|
{ |
|
zoom--; |
|
} |
|
else |
|
{ |
|
//zoom++; |
|
} |
|
} |
|
catch { } |
|
} |
|
} |
|
|
|
const float rad2deg = (float)(180 / Math.PI); |
|
const float deg2rad = (float)(1.0 / rad2deg); |
|
|
|
public Vector3 Normal(Vector3 a, Vector3 b, Vector3 c) |
|
{ |
|
var dir = Vector3.Cross(b - a, c - a); |
|
var norm = Vector3.Normalize(dir); |
|
return norm; |
|
} |
|
|
|
|
|
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) |
|
{ |
|
if (this.DesignMode) |
|
return; |
|
|
|
if (area.LocationMiddle.Lat == 0 && area.LocationMiddle.Lng == 0) |
|
return; |
|
|
|
_angle+=1f; |
|
|
|
// area.LocationTopLeft = new PointLatLng(area.LocationTopLeft.Lat + 0.0001,area.LocationTopLeft.Lng); |
|
|
|
//area.Size = new SizeLatLng(0.1, 0.1); |
|
|
|
try |
|
{ |
|
base.OnPaint(e); |
|
|
|
} |
|
catch { return; } |
|
|
|
double heightscale = (step / 90.0) * 1; |
|
|
|
float scale = 1.0f; |
|
|
|
float radians = (float)(Math.PI * (rpy.Z * -1) / 180.0f); |
|
|
|
//radians = 0; |
|
|
|
float mouseY = (float)(0.1 * scale); |
|
|
|
cameraX = area.LocationMiddle.Lng; // multiplying by mouseY makes the |
|
cameraZ = area.LocationMiddle.Lat; // camera get closer/farther away with mouseY |
|
cameraY = (LocationCenter.Alt < srtm.getAltitude(cameraZ, cameraX, 20)) ? (srtm.getAltitude(cameraZ, cameraX, 20)+ 0.2) * heightscale : LocationCenter.Alt * heightscale;// (srtm.getAltitude(lookZ, lookX, 20) + 100) * heighscale; |
|
|
|
|
|
lookX = area.LocationMiddle.Lng + Math.Sin(radians) * mouseY; ; |
|
lookY = cameraY; |
|
lookZ = area.LocationMiddle.Lat + Math.Cos(radians) * mouseY; ; |
|
|
|
|
|
MakeCurrent(); |
|
|
|
|
|
GL.MatrixMode(MatrixMode.Projection); |
|
|
|
OpenTK.Matrix4 projection = OpenTK.Matrix4.CreatePerspectiveFieldOfView(60 * deg2rad, 1f, 0.00001f, 5000.0f); |
|
GL.LoadMatrix(ref projection); |
|
|
|
Matrix4 modelview = Matrix4.LookAt((float)cameraX, (float)cameraY, (float)cameraZ, (float)lookX, (float)lookY, (float)lookZ, 0,1,0); |
|
GL.MatrixMode(MatrixMode.Modelview); |
|
|
|
// roll |
|
modelview = Matrix4.Mult(modelview,Matrix4.CreateRotationZ (rpy.X * deg2rad)); |
|
// pitch |
|
modelview = Matrix4.Mult(modelview, Matrix4.CreateRotationX(rpy.Y * -deg2rad)); |
|
|
|
GL.LoadMatrix(ref modelview); |
|
|
|
GL.ClearColor(Color.Blue); |
|
|
|
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); |
|
|
|
GL.LightModel(LightModelParameter.LightModelAmbient,new float[] {1f,1f,1f,1f}); |
|
|
|
GL.Enable(EnableCap.Texture2D); |
|
GL.BindTexture(TextureTarget.Texture2D, texture); |
|
/* |
|
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(); |
|
*/ |
|
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); |
|
|
|
sw.Start(); |
|
|
|
zoom = 11; |
|
|
|
getImage(); |
|
|
|
sw.Stop(); |
|
|
|
Console.WriteLine("img " +sw.ElapsedMilliseconds); |
|
|
|
sw.Start(); |
|
|
|
double increment = step *5; |
|
|
|
double cleanup = area.Bottom % increment; |
|
double cleanup2 = area.Left % increment; |
|
|
|
|
|
|
|
for (double z = (area.Bottom - cleanup); z < area.Top - step; z += increment) |
|
{ |
|
//Makes OpenGL draw a triangle at every three consecutive vertices |
|
GL.Begin(BeginMode.TriangleStrip); |
|
for (double x = (area.Left - cleanup2); x < area.Right - step; x += increment) |
|
{ |
|
int heightl = srtm.getAltitude(z, area.Right + area.Left - x, 20); |
|
|
|
// Console.WriteLine(x + " " + z); |
|
|
|
GL.Color3(Color.White); |
|
|
|
|
|
// int heightl = 0; |
|
|
|
double scale2 = (Math.Abs(x - area.Left) / area.WidthLng);// / (float)_terrain.Width; |
|
|
|
double scale3 = (Math.Abs(z - area.Bottom) / area.HeightLat);// / (float)_terrain.Height; |
|
|
|
double imgx = 1 - scale2; |
|
double imgy = 1 - scale3; |
|
// GL.Color3(Color.Red); |
|
|
|
//GL.Color3(_terrain.GetPixel(imgx, imgy)); |
|
GL.TexCoord2(imgx,imgy); |
|
GL.Vertex3(x, heightl * heightscale, z); // _terrain.GetPixel(x, z).R |
|
|
|
try |
|
{ |
|
heightl = srtm.getAltitude(z + increment, area.Right + area.Left - x, 20); |
|
|
|
//scale2 = (Math.Abs(x - area.Left) / area.WidthLng) * (float)_terrain.Width; |
|
|
|
scale3 = (Math.Abs(((z + increment) - area.Bottom)) / area.HeightLat);// / (float)_terrain.Height; |
|
|
|
imgx = 1- scale2; |
|
imgy = 1 - scale3; |
|
// GL.Color3(Color.Green); |
|
//GL.Color3(_terrain.GetPixel(imgx, imgy)); |
|
GL.TexCoord2(imgx,imgy); |
|
GL.Vertex3(x, heightl * heightscale, z + increment); |
|
|
|
// Console.WriteLine(x + " " + (z + step)); |
|
} |
|
catch { break; } |
|
|
|
} |
|
GL.End(); |
|
} |
|
|
|
GL.Enable(EnableCap.Blend); |
|
GL.DepthMask(false); |
|
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One); |
|
GL.DepthMask(true); |
|
GL.Disable(EnableCap.Blend); |
|
|
|
GL.Flush(); |
|
|
|
|
|
sw.Stop(); |
|
|
|
Console.WriteLine("GL "+sw.ElapsedMilliseconds); |
|
|
|
this.SwapBuffers(); |
|
|
|
//this.Invalidate(); |
|
} |
|
|
|
private void InitializeComponent() |
|
{ |
|
this.SuspendLayout(); |
|
// |
|
// OpenGLtest |
|
// |
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); |
|
this.Name = "OpenGLtest"; |
|
this.Load += new System.EventHandler(this.test_Load); |
|
this.Resize += new System.EventHandler(this.test_Resize); |
|
this.ResumeLayout(false); |
|
|
|
} |
|
|
|
private void test_Load(object sender, EventArgs e) |
|
{ |
|
GL.Enable(EnableCap.DepthTest); |
|
// GL.Enable(EnableCap.Light0); |
|
GL.Enable(EnableCap.Lighting); |
|
GL.Enable(EnableCap.ColorMaterial); |
|
GL.Enable(EnableCap.Normalize); |
|
|
|
//GL.Enable(EnableCap.LineSmooth); |
|
//GL.Enable(EnableCap.PointSmooth); |
|
//GL.Enable(EnableCap.PolygonSmooth); |
|
GL.ShadeModel(ShadingModel.Smooth); |
|
GL.Enable(EnableCap.CullFace); |
|
GL.Enable(EnableCap.Texture2D); |
|
|
|
} |
|
|
|
private void test_Resize(object sender, EventArgs e) |
|
{ |
|
MakeCurrent(); |
|
|
|
GL.Viewport(0, 0, this.Width, this.Height); |
|
|
|
this.Invalidate(); |
|
} |
|
} |
|
}
|
|
|