using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using OpenTK; using OpenTK.Graphics.OpenGL; using MathNet.Numerics.LinearAlgebra.Single; using bbiwarg.DataSource; namespace bbiwarg.Graphics { class Output : GameWindow { private IVideoDataSource source; private uint imageBufferId, pointBufferId; public Output(IVideoDataSource source) { this.source = source; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); Title = "OutputTest"; GL.ClearColor(Color.Black); initBuffers(); } protected override void OnRenderFrame(FrameEventArgs e) { base.OnRenderFrame(e); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, -Vector3.UnitZ, Vector3.UnitY); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref modelview); source.releaseFrame(); source.updateFrame(); Stopwatch sw = new Stopwatch(); sw.Start(); GL.EnableClientState(ArrayCap.VertexArray); GL.EnableClientState(ArrayCap.ColorArray); GL.BindBuffer(BufferTarget.ArrayBuffer, imageBufferId); source.setVertexBuffer(GL.MapBuffer(BufferTarget.ArrayBuffer, BufferAccess.WriteOnly)); source.createVertexArray(); GL.UnmapBuffer(BufferTarget.ArrayBuffer); GL.VertexPointer(3, VertexPointerType.Float, 3 * sizeof(float) + 4 * sizeof(byte), IntPtr.Zero); GL.ColorPointer(4, ColorPointerType.UnsignedByte, 3 * sizeof(float) + 4 * sizeof(byte), 3 * sizeof(float)); ImageData data = source.getImageData(); GL.PointSize(3.0f); GL.DrawArrays(PrimitiveType.Points, 0, data.getHeight() * data.getWidth()); // draw points float[] pointData; DetectionStatus[] fingerStatus = source.getFingerStatus(1); int numFingersDetected = 0; for (int i = 0; i < fingerStatus.Length; ++i) { if (fingerStatus[i] == DetectionStatus.Detected || fingerStatus[i] == DetectionStatus.Tracked) ++numFingersDetected; } pointData = new float[(4 + 3) * (1 + numFingersDetected)]; Color y = Color.Yellow; Vector palmPosition = source.getPalmPosition3D(1); pointData[0] = palmPosition[0]; pointData[1] = palmPosition[2]; pointData[2] = -palmPosition[1]; pointData[3] = y.R / 255.0f; pointData[4] = y.G / 255.0f; pointData[5] = y.B / 255.0f; pointData[6] = y.A / 255.0f; int index = 7; Vector[] fingerPositions = source.getFingerTipPositions3D(1); for (int i = 0; i < fingerStatus.Length; ++i) { if (fingerStatus[i] == DetectionStatus.Detected || fingerStatus[i] == DetectionStatus.Tracked) { pointData[index + 0] = fingerPositions[i][0]; pointData[index + 1] = fingerPositions[i][2]; pointData[index + 2] = -fingerPositions[i][1]; pointData[index + 3] = y.R / 255.0f; pointData[index + 4] = y.G / 255.0f; pointData[index + 5] = y.B / 255.0f; pointData[index + 6] = y.A / 255.0f; index += 7; } } GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ArrayBuffer, pointBufferId); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(pointData.Length * sizeof(float)), pointData, BufferUsageHint.DynamicDraw); GL.VertexPointer(3, VertexPointerType.Float, (4 + 3) * sizeof(float), IntPtr.Zero); GL.ColorPointer(4, ColorPointerType.Float, (4 + 3) * sizeof(float), 3 * sizeof(float)); GL.PointSize(10f); GL.DrawArrays(PrimitiveType.Points, 0, pointData.Length / (4 + 3)); sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); SwapBuffers(); } protected override void OnResize(EventArgs e) { base.OnResize(e); GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height); Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 3, Width / (float)Height, 0.01f, 3.0f); GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref projection); } private void initBuffers() { GL.GenBuffers(1, out imageBufferId); GL.GenBuffers(1, out pointBufferId); ImageData data = source.getImageData(); GL.BindBuffer(BufferTarget.ArrayBuffer, imageBufferId); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)((3 * sizeof(float) + 4 * sizeof(byte)) * data.getWidth() * data.getHeight()), IntPtr.Zero, BufferUsageHint.StreamDraw); } } }