using System; using System.IO; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.Threading; using System.Threading.Tasks; using System.Collections.Generic; using OpenTK; using OpenTK.Input; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; namespace NewNewThing { class MainClass { public static void Main(string[] args) { Console.WriteLine("Loading..."); GameWindow window = new GameWindow(800, 600, GraphicsMode.Default, "SimuVerse", GameWindowFlags.Default); window.KeyDown += (sender, e) => { if (e.Key == Key.Escape) { window.Close(); } }; List Entities = new List(); window.Load += (sender, e) => { Random Seed = new Random(); int ECount = Seed.Next(5000, 5000); Console.WriteLine("Generating " + ECount + " entities..."); for (int i = 0; i < ECount; i++) { float Salt = Seed.Next(1, 1000) / 100f; Entities.Add(new Entity() { Mass = Salt * Salt * Salt, Size = Salt, Position = new Vector2(Seed.Next(-5000, 5000), Seed.Next(-5000, 5000)) }); } GL.ClearColor(Color4.Black); GL.Enable(EnableCap.Texture2D); Bitmap bmp = new Bitmap("circle.png"); int texture = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, texture); BitmapData bmp_data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp_data.Width, bmp_data.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmp_data.Scan0); bmp.UnlockBits(bmp_data); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureCompareMode, (int)TextureCompareMode.CompareRefToTexture); bmp.Dispose(); }; window.VSync = VSyncMode.Off; float time = 0; float zoom = 10; float centerX = 0; float centerY = 0; window.RenderFrame += (sender, e) => { if (Keyboard.GetState().IsKeyDown(Key.Q)) { zoom *= (float)e.Time + 1; } if (Keyboard.GetState().IsKeyDown(Key.E)) { zoom *= 1 - (float)e.Time; } if (Keyboard.GetState().IsKeyDown(Key.A)) { centerX += 10; } if (Keyboard.GetState().IsKeyDown(Key.D)) { centerX -= 10; } if (Keyboard.GetState().IsKeyDown(Key.W)) { centerY += 10; } if (Keyboard.GetState().IsKeyDown(Key.S)) { centerY -= 10; } time += (float)e.Time; GL.Clear(ClearBufferMask.ColorBufferBit); GL.LoadIdentity(); GL.Ortho(-window.Width * zoom, window.Width * zoom, window.Height * zoom, -window.Height * zoom, -1, 1); GL.Translate(centerX, centerY, 0); foreach(Entity n in Entities) { n.Render(); } float etime = (float)e.Time; //for (int i = 0; i < Entities.Count; i++) //{ int cap = Entities.Count; Parallel.For(0, cap, (i) => { if (i >= cap) { return; } Entity n = Entities[i]; n.Tick(etime); for (int j = i + 1; j < Entities.Count; j++) { Entity a = Entities[j]; Vector2 distance = a.Position - n.Position; if (distance.LengthSquared <= (a.Size + n.Size) * (a.Size + n.Size)) { Entities.RemoveAt(j); j--; cap--; n.Size = (float)Math.Pow(a.Mass + n.Mass, 1.0 / 3.0); n.Mass += a.Mass; n.Position = (n.Position * n.Mass + a.Position * a.Mass) / (n.Mass + a.Mass); n.Velocity = (n.Velocity * n.Mass + a.Velocity * a.Mass) / (n.Mass + a.Mass) * etime; } else { n.Velocity += (a.Mass * distance / distance.LengthSquared) / n.Mass * etime; a.Velocity += (a.Mass * distance / distance.LengthSquared) / a.Mass * etime; } } }); window.SwapBuffers(); }; window.Run(1, 60); } } }