using System; using System.Collections.Generic; 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 Point[,] depthPixels = new Point[320,240]; private ImageData currentImage; private List graphicElements = new List(); private int VBOid = new int(); private int IBOid = new int(); private float[] vertices = new float[0]; private uint[] triangles = new uint[0]; private float maxDelta = 0; public Output(IVideoDataSource source) { this.source = source; currentImage = source.getImageData(); } protected override void OnLoad(EventArgs e) { base.OnLoad(e); Title = "OutputTest"; GL.ClearColor(Color.Black); initializeDepthPixels(); 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(); currentImage = source.getImageData(); updateDepthPixels(); updateBuffer(); drawBuffer(); 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 / 4, Width / (float)Height, 1.0f, 3000.0f); GL.MatrixMode(MatrixMode.Projection); GL.LoadMatrix(ref projection); } private void initializeDepthPixels() { int width = currentImage.getWidth(); int height = currentImage.getHeight(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Vertex vertex = new Vertex(x, y, 0.0f); Color color = Color.White; float size = 0.5f; Point pixel = new Point(vertex, color, size); depthPixels[x, y] = pixel; graphicElements.Add(pixel); } } } private void updateDepthPixels() { for (int x = 0; x < currentImage.getWidth(); x++) { for (int y = 0; y < currentImage.getHeight(); y++) { Point depthPixel = depthPixels[x, y]; depthPixel.position.z = currentImage.getDepth(x, y); depthPixel.color = currentImage.getColor(x, y); } } } private void initBuffers() { GL.EnableClientState(ArrayCap.VertexArray); GL.GenBuffers(1, out VBOid); GL.GenBuffers(1, out IBOid); GL.BindBuffer(BufferTarget.ArrayBuffer, VBOid); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * sizeof(float)), vertices, BufferUsageHint.StreamDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, IBOid); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(triangles.Length * sizeof(int)), triangles, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); } public void updateBuffer() { List verticesData = new List(); List triangleData = new List(); foreach (IGraphicElement graphicElement in graphicElements) { List elementVertices = graphicElement.getVertices(currentImage.getWidth(), currentImage.getHeight()); uint[] elementTriangles = graphicElement.getTriangleIndices(); Color elementColor = graphicElement.getColor(); uint c = (uint)verticesData.Count / 6; foreach (Vector elementVertex in elementVertices) { verticesData.AddRange(convertColor(elementColor)); verticesData.AddRange(elementVertex); } for (int i = 0; i < elementTriangles.Length; i++) { triangleData.Add(elementTriangles[i] + c); } } vertices = verticesData.ToArray(); triangles = triangleData.ToArray(); GL.BindBuffer(BufferTarget.ArrayBuffer, VBOid); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * sizeof(float)), vertices, BufferUsageHint.StreamDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, IBOid); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(triangles.Length * sizeof(int)), triangles, BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); } private void drawBuffer() { GL.BindBuffer(BufferTarget.ArrayBuffer, VBOid); GL.BindBuffer(BufferTarget.ElementArrayBuffer, IBOid); GL.InterleavedArrays(InterleavedArrayFormat.C3fV3f, 0, IntPtr.Zero); GL.DrawElements(BeginMode.Triangles, triangles.Length, DrawElementsType.UnsignedInt, 0); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); } private List convertColor(Color color) { List result = new List(); result.Add(color.R / 255f); result.Add(color.G / 255f); result.Add(color.B / 255f); return result; } } }