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(@"^MarkerRemove cam=(.*) id=(.*)", UnShowStrip );
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();
}*/
}
///
/// 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 UnShowStrip(object sender, IvyMessageEventArgs e)
{
string camId = e[0];
int markerId = int.Parse(e[1]);
//Find the corresponding strip
int idIndex = -1;
//remove the strip if all tags not vilible
ProjectedStrip strip = ProjectedStrip.FindStrip(ProjectedStrips, markerId, out idIndex);
if (strip != null)
{
//strip.
NeedRefresh = true;
}
}
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();
}
}
}