using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OpenTK.Graphics.OpenGL; using System.Threading; using OpenTK; using System.Drawing.Imaging; using IvyBus; using System.Globalization; using AnotoData; namespace ProjectedStripBoard { public partial class FormProjectedStripBoard : Form { ProjectedStrip.DrawingMod TheDrawingMode = ProjectedStrip.DrawingMod.Normal; string IvyDomaine = "10.192.35.255:3000"; /// /// In order to prevent lot of refresh, the refresh occurses once every 100ms if needed /// public bool NeedRefresh = false; public bool DrawBoarder = true; OpenTK.GLControl GlControl; Vector2[] Square; Bitmap BitmapBack = new Bitmap("bois.bmp"); int IdBitmapBack = -1; Bitmap Texture; public List ProjectedStrips = new List(); CultureInfo CI = new CultureInfo("en-US"); public FormProjectedStripBoard() { InitializeComponent(); } private void FormProjectedStripBoard_Resize(object sender, EventArgs e) { Texture = new Bitmap(this.Width, this.Height); RebuildTexture(); } /// /// To sum up, there were three errors. Two in loading the textures: /// 1. Not binding the texture after GenTexture() (believing this to be implicit) /// 2. Not setting texture parameters after loading each texture (believing these to be "global" to all loaded textures) /// and one in rendering: /// 3. Binding textures between Begin() and End() /// void LoadTexture(out int textureID, Bitmap bmp) { textureID = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, textureID); BitmapData data = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0); bmp.UnlockBits(data); GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.NearestMipmapLinear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); //GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); //GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); } void ReleaseTexture() { GL.DeleteTexture(IdBitmapBack); } private void FormProjectedStripBoard_Load(object sender, EventArgs e) { // Creates a 3.0-compatible GraphicsContext with 32bpp color, 24bpp depth // 8bpp stencil and 4x anti-aliasing. GlControl = new GLControl(new OpenTK.Graphics.GraphicsMode(32, 24, 8, 4)); // GlControl = new OpenTK.GLControl(); GlControl.Dock = DockStyle.Fill; GlControl.Paint += new PaintEventHandler(GlControl_Paint); GlControl.MouseDown += new MouseEventHandler(GlControl_MouseDown); GlControl.Resize += new EventHandler(GlControl_Resize); GlControl.MouseMove += new MouseEventHandler(GlControl_MouseMove); GlControl.MouseUp += new MouseEventHandler(GlControl_MouseUp); GlControl.MouseDoubleClick += new MouseEventHandler(GlControl_MouseDoubleClick); this.Controls.Add(GlControl); Square = new Vector2[4]; Square[0] = new Vector2( -0.7666667f,1.004822f);//(-1, 1); Square[1] = new Vector2(0.775f,1.015067f);//(1, 1); Square[2] = new Vector2(0.7770831f,-0.9435025f);//(1, -1); Square[3] = new Vector2(-0.7760416f,-0.9792843f);//(-1, -1); /* Square[0] = new Vector2(-0.6458333f, 0.7694166f);//(-1, 1); Square[1] = new Vector2(0.6333334f, 0.7702448f);//(1, 1); Square[2] = new Vector2(0.6604165f, -0.717514f);//(1, -1); Square[3] = new Vector2(-0.6499999f, -0.7551789f);//(-1, -1); */ GL.ClearColor(Color.MidnightBlue); GL.Disable(EnableCap.CullFace); GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.Texture2D); GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest); //Build the menuItem foreach (var item in typeof(ProjectedStrip.DrawingMod).GetEnumNames()) { drawingModeToolStripMenuItem.DropDownItems.Add(item); drawingModeToolStripMenuItem.DropDownItems[drawingModeToolStripMenuItem.DropDownItems.Count - 1].Click += new EventHandler(FormProjectedStripBoard_Click); } //Load the available projected strip board ProjectedStrips = new List(); AnotoStrip[] Strips = AnotoStrip.LoadFileStrip("Strips.csv"); foreach (var item in Strips) { ProjectedStrip ps = new ProjectedStrip(item); ProjectedStrips.Add(ps); } RebuildTexture(); // LoadTexture(out IdBitmapBack, BitmapBack); //Start ivy IvyBus.ivy.Start(IvyDomaine); // IvyBus.ivy.BindMsg(@"ShowStrip FlightId=([0-9]+) Name=(.*) Show=(True|False) x=(.*) y=(.*)", ShowStrip, null); IvyBus.ivy.BindMsg(@"MarkerMoveCalibrated cam=(.*) id=(.*) time=(.*) confidence=(.*) area=(.*) dir=(.*) x=(.*) y=(.*)", ShowStrip, null); IvyBus.ivy.BindMsg(@"SeleteAircraftFromRadarScreen AircraftId=(.*)", SeleteAircraftFromRadarScreen, null); // IvyBus.ivy.BindMsg(@"MarkerMove cam=(.*)", ShowStrip, null); // ShowStrip FlightId=123 Name=toto Show=True x=0.5 y=0.5 ", // arg0='MarkerMove cam= id=5 time=638.312 confidence=0.500 area=2519 dir=0 x=969.009 y=463.248 distance=1153577.511' } ToolStripMenuItem CheckMenuItemDrawingMode = null; /// /// Click on a drawing mode /// /// /// void FormProjectedStripBoard_Click(object sender, EventArgs e) { ToolStripMenuItem ddi = (ToolStripMenuItem)sender; if (CheckMenuItemDrawingMode != null) CheckMenuItemDrawingMode.Checked = false; CheckMenuItemDrawingMode = ddi; CheckMenuItemDrawingMode.Checked = true; TheDrawingMode = (ProjectedStrip.DrawingMod)Enum.Parse(typeof(ProjectedStrip.DrawingMod), ddi.Text); NeedRefresh = true; } private void SeleteAircraftFromRadarScreen(object sender, IvyMessageEventArgs e) { string aircraftId = e[0]; ProjectedStrip selectedProjectedStrip = null; foreach (var projStrip in ProjectedStrips) { if (projStrip.TheAnotoStrip.CallSign == aircraftId) { projStrip.IsSelected = true; selectedProjectedStrip = projStrip; } else { projStrip.IsSelected = false; } } if (selectedProjectedStrip == null) { char [] sep = {';'}; //The user selected an unknown strip, then create it... string unknowStripText = aircraftId+";?;?;?;?;?;?;?;?;?;?;?;?;?;?;;;?;?;;;?;?;;;?;-1;-1;-1;-1;-1"; AnotoStrip unknownStrip = new AnotoStrip(unknowStripText.Split(sep)); ProjectedStrip unknownProjectedStrip = new ProjectedStrip(unknownStrip); unknownProjectedStrip.IsSelected = true; ProjectedStrips.Add(unknownProjectedStrip); } //Highlight The corresponding strip } /// /// IvyBus.ivy.BindMsg(@" /// MarkerMove cam=(.*) id=(.*) time=(.*) confidence=(.*) area=(.*) dir=(.*) x=(.*) y=(.*) distance=(.*)", ShowStrip, null); /// 0 1 2 3 4 5 6 7 8 /// /// /// private void ShowStrip(object sender, IvyMessageEventArgs e) { string camId = e[0]; int markerId = int.Parse(e[1]); float time = float.Parse(e[2], CI); float confidence = float.Parse(e[3], CI); float area = float.Parse(e[4], CI); float dir = float.Parse(e[5], CI); float x = float.Parse(e[6], CI); float y = float.Parse(e[7], CI); // float distance = float.Parse(e[8], CI); //remove the strip //Find the corresponding strip int idIndex = -1; ProjectedStrip strip = ProjectedStrip.FindStrip(ProjectedStrips, markerId, out idIndex); if (strip != null) { strip.UpdatePosition(idIndex, x, y); NeedRefresh = true; } /* else { List ids = new List(); ids.Add(markerId); ProjectedStrip ps = new ProjectedStrip(ids); ps.Postition = new Vector2(x, y); ProjectedStrips.Add(ps); }*/ // RebuildTexture(); /* if (trueFalse == "True") { //Show the strip ProjectedStrip strip = ProjectedStrip.FindStrip(ProjectedStrips, name); if (strip != null) ProjectedStrips.Remove(strip); ProjectedStrip ps = new ProjectedStrip(); ps.Name = name; ps.Postition = new Vector2(x, y); ProjectedStrips.Add(ps); RebuildTexture(); }*/ } private void RebuildTexture() { NeedRefresh = true; } void GlControl_MouseDoubleClick(object sender, MouseEventArgs e) { if (this.FormBorderStyle == System.Windows.Forms.FormBorderStyle.SizableToolWindow) this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; else this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; } void GlControl_MouseUp(object sender, MouseEventArgs e) { IsPointMoving = false; } bool IsPointMoving = false; int IndexMovingPoint = -1; Vector2 PtMouseDown; void GlControl_MouseMove(object sender, MouseEventArgs e) { if (IsPointMoving) { Vector2 MousePos = new Vector2(((float)e.X / (float)GlControl.Width) * 2 - 1, 1 - ((float)e.Y / (float)GlControl.Height) * 2); Square[IndexMovingPoint].X += -PtMouseDown.X + MousePos.X; Square[IndexMovingPoint].Y -= PtMouseDown.Y - MousePos.Y; PtMouseDown = MousePos; Repaint(); } } void GlControl_Resize(object sender, EventArgs e) { if (GlControl.ClientSize.Height == 0) GlControl.ClientSize = new System.Drawing.Size(GlControl.ClientSize.Width, 1); Texture = new Bitmap(this.Width, this.Height); GL.Viewport(0, 0, GlControl.ClientSize.Width, GlControl.ClientSize.Height); } void GlControl_MouseDown(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) { Point pt = this.PointToScreen(e.Location); TheContextMenuStrip.Show(pt); } if (e.Button == System.Windows.Forms.MouseButtons.Left) { //find the closest point PtMouseDown = new Vector2(((float)e.X / (float)GlControl.Width) * 2 - 1, 1 - ((float)e.Y / (float)GlControl.Height) * 2); IndexMovingPoint = GetClosestPoint(PtMouseDown); if (IndexMovingPoint != -1) IsPointMoving = true; } } private int GetClosestPoint(Vector2 pt) { float d0 = (Square[0] - pt).Length; float d1 = (Square[1] - pt).Length; float d2 = (Square[2] - pt).Length; float d3 = (Square[3] - pt).Length; if (d0 < d1) if (d0 < d2) if (d0 < d3) return 0; if (d1 < d0) if (d1 < d2) if (d1 < d3) return 1; if (d2 < d0) if (d2 < d1) if (d2 < d3) return 2; if (d3 < d0) if (d3 < d1) if (d3 < d2) return 3; return -1; } void GlControl_Paint(object sender, PaintEventArgs e) { GlControl.MakeCurrent(); GL.ClearColor(BackGroundColor);// Color.DarkGray); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMagFilter.Linear); float length = 10; Vector2[,] pts = new Vector2[(int)length + 1, (int)length + 1]; //Vector2 p0 = new Vector2(Square[0].X, Square[0].Y); //Vector2 p1 = new Vector2(Square[1].X, Square[1].Y); Vector2 p0 = new Vector2(); Vector2 p1 = new Vector2(); for (int y = 0; y <= length; y++) { //Inc p0, p1 p0.X = Square[0].X + (Square[3].X - Square[0].X) / length * (float)y; p0.Y = Square[0].Y + (Square[3].Y - Square[0].Y) / length * (float)y; p1.X = Square[1].X + (Square[2].X - Square[1].X) / length * (float)y; p1.Y = Square[1].Y + (Square[2].Y - Square[1].Y) / length * (float)y; //compute dx and dy float dx = (p1.X - p0.X) / length; float dy = (p1.Y - p0.Y) / length; for (int x = 0; x <= length; x++) { pts[x, y] = new Vector2(p0.X + x * dx, p0.Y + x * dy); } } //Draw the texture GL.BindTexture(TextureTarget.Texture2D, IdBitmapBack); float incT = 1.0f / (length); for (int y = 0; y < (length); y++) { for (int x = 0; x < (length); x++) { //GL.Begin(BeginMode.Points); //GL.Color4(Color.White); //GL.Vertex2(pts[x, y]); //GL.End(); GL.Begin(BeginMode.Quads); GL.TexCoord2(incT * (float)x, incT * (float)y); GL.Vertex2(pts[x, y]); GL.TexCoord2(incT * (float)(x), incT * (float)(y + 1)); GL.Vertex2(pts[x, y + 1]); GL.TexCoord2(incT * (float)(x + 1), incT * (float)(y + 1)); GL.Vertex2(pts[x + 1, y + 1]); GL.TexCoord2(incT * (float)(x + 1), incT * (float)(y)); GL.Vertex2(pts[x + 1, y]); GL.End(); } } //GL.End(); //GL.BindTexture(TextureTarget.Texture2D, IdBitmapBack); //GL.Begin(BeginMode.Quads); //GL.Color3(Color.White); //GL.TexCoord2(0, 0); GL.Vertex2(Square[0]); //GL.TexCoord2(0, 1.0f); GL.Vertex2(Square[1]); //GL.TexCoord2(1.0f, 1.0f); GL.Vertex2(Square[2]); //GL.TexCoord2(1.0f, 0.0f); GL.Vertex2(Square[3]); //GL.End(); GlControl.SwapBuffers(); Thread.Sleep(1); } private void DrawSquare(Vector2 p, float w, float h, float w1, float h1) { GL.Begin(BeginMode.Quads); GL.TexCoord2(0, 0); GL.Vertex2(p.X, p.Y); GL.TexCoord2(0, 1.0f); GL.Vertex2(p.X + w, p.Y); GL.TexCoord2(1.0f, 1.0f); GL.Vertex2(p.X + w1, p.Y + h1); GL.TexCoord2(1.0f, 0.0f); GL.Vertex2(p.X, p.Y + h); GL.End(); } private Color BackGroundColor = Color.Black; private void Repaint() { GlControl.Invalidate(); } private void changeBackgroundColorToolStripMenuItem_Click(object sender, EventArgs e) { ColorDialog cDialog = new ColorDialog(); if (cDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { BackGroundColor = cDialog.Color; RebuildTexture(); } } private void ivySetupToolStripMenuItem_Click(object sender, EventArgs e) { FormIvySetup IvySetup = new FormIvySetup(); IvySetup.ivyDomain1.Domain = IvyDomaine; if (IvySetup.ShowDialog() == System.Windows.Forms.DialogResult.OK) { IvyDomaine = IvySetup.ivyDomain1.Domain; IvyBus.ivy.Stop(); IvyBus.ivy.Start(IvyDomaine); } } private void timerRefresh_Tick(object sender, EventArgs e) { if (NeedRefresh) { NeedRefresh = false; if (Texture == null) Texture = new Bitmap(this.Width, this.Height); Graphics g = Graphics.FromImage(Texture); // g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; // float borderW = 10.0f; //Clear the Bitmap g.FillRectangle(new SolidBrush(BackGroundColor), 0, 0, this.Width, this.Height); Vector2 correctedPosTopLeft = ProjectedStrip.GetCorrectedPostion(new Vector2(0, 0)); Vector2 correctedPosBottomRight = ProjectedStrip.GetCorrectedPostion(new Vector2(1, 1)); g.DrawRectangle(Pens.White, 0, 0, this.Width-1, this.Height-1); g.FillRectangle(new SolidBrush(BackGroundColor), correctedPosTopLeft.X * Texture.Width, correctedPosTopLeft.Y * Texture.Height, correctedPosBottomRight.X * Texture.Width - correctedPosTopLeft.X * Texture.Width, correctedPosBottomRight.Y * Texture.Height - correctedPosTopLeft.Y * Texture.Height); //Draw the four markers float w = 5; g.FillEllipse(Brushes.Red, correctedPosTopLeft.X * Texture.Width - w / 2, correctedPosTopLeft.Y * Texture.Height - w / 2, w, w); g.FillEllipse(Brushes.Red, correctedPosBottomRight.X * Texture.Width - w / 2, correctedPosBottomRight.Y * Texture.Height - w / 2, w, w); g.FillEllipse(Brushes.Red, correctedPosTopLeft.X * Texture.Width - w / 2, correctedPosBottomRight.Y * Texture.Height - w / 2, w, w); g.FillEllipse(Brushes.Red, correctedPosBottomRight.X * Texture.Width - w / 2, correctedPosTopLeft.Y * Texture.Height - w / 2, w, w); /* if (DrawBoarder) { // g.FillRectangle(new SolidBrush(Color.White), 0, 0, Texture.Width, Texture.Height); g.DrawRectangle(new Pen(Color.White, borderW), correctedPosTopLeft.X * Texture.Width, correctedPosTopLeft.Y * Texture.Height, correctedPosBottomRight.X * Texture.Width - correctedPosTopLeft.X * Texture.Width, correctedPosBottomRight.Y * Texture.Height - correctedPosTopLeft.Y * Texture.Height); }*/ // g.DrawRectangle(new Pen(Color.White), borderW, borderW, Texture.Width - borderW, Texture.Height - borderW); foreach (var strip in ProjectedStrips) { strip.Draw(TheDrawingMode, BackGroundColor, g, Texture.Width, Texture.Height, Font); //Clear the visible tag list // strip.ClearVisibleTags(); } if (IdBitmapBack != -1) ReleaseTexture(); LoadTexture(out IdBitmapBack, Texture); Repaint(); } } private void testToolStripMenuItem_Click(object sender, EventArgs e) { Random rnd = new Random(); foreach (var item in ProjectedStrips) { item.Postition = new Vector2((float)rnd.NextDouble(), (float)rnd.NextDouble()); for (int i = 0; i < item.VisibleTags.Length; i++) { item.VisibleTags[i] = true; } } NeedRefresh = true; } private void whiteBoarderToolStripMenuItem_Click(object sender, EventArgs e) { whiteBoarderToolStripMenuItem.Checked = !whiteBoarderToolStripMenuItem.Checked; DrawBoarder = whiteBoarderToolStripMenuItem.Checked; NeedRefresh = true; } private void setDetlaParamToolStripMenuItem_Click(object sender, EventArgs e) { FormDeltaParam f = new FormDeltaParam(this); f.populateData(ProjectedStrip.DX, ProjectedStrip.DY, ProjectedStrip.MarkerWidth, ProjectedStrip.MarkerHeight, ProjectedStrip.TopLeft, ProjectedStrip.BottomRight, Square); f.Show(); } internal void Set(float dx, float dy, float MarkerHeight, float MarkerWidth, float MinX, float MinY, float MaxX, float MaxY) { //Set the visual parameters ProjectedStrip.DX = dx; ProjectedStrip.DY = dy; ProjectedStrip.MarkerWidth = MarkerWidth; ProjectedStrip.MarkerHeight = MarkerHeight; ProjectedStrip.TopLeft = new Vector2(MinX,MinY); ProjectedStrip.BottomRight = new Vector2(MaxX,MaxY); NeedRefresh = true; } private void exitToolStripMenuItem_Click(object sender, EventArgs e) { this.Close(); } } }