using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; namespace s2t1 { class Triangle { public Vector4 Color { get; set; } public Vector2d Scale { get; set; } public Vector2d InitialPosition { get; set; } public Vector2d AbsSpeed { get; set; } public Triangle() : this(Vector4.One) { } public Triangle(Vector4 color, float scale = 0.2f) : this(color, scale, Vector2d.Zero, Vector2d.Zero) { } public Triangle(Vector4 color, float scale, Vector2d position, Vector2d speed) : this(color, scale * Vector2d.One, Vector2d.Zero, Vector2d.Zero) { } public Triangle(Vector4 color, Vector2d scale, Vector2d position, Vector2d speed) { Color = color; Scale = scale; InitialPosition = position; AbsSpeed = speed; GL.GenVertexArrays(1, out _vao); GL.BindVertexArray(_vao); GL.GenBuffers(1, out _vbo); GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo); GL.BufferData(BufferTarget.ArrayBuffer, _vertices.Length * sizeof(float), _vertices, BufferUsageHint.StaticDraw); GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, _stride, 0); GL.EnableVertexAttribArray(0); GL.GenBuffers(1, out _ebo); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _ebo); GL.BufferData(BufferTarget.ElementArrayBuffer, _indicies.Length * sizeof(int), _indicies, BufferUsageHint.StaticDraw); GL.BindVertexArray(0); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); } public void Draw(int shader, Matrix4 model, double time0, Vector2d speed0) { model = model * Lorentz(AbsSpeed - speed0) * GetTransform(time0, speed0); GL.UniformMatrix4(GL.GetUniformLocation(shader, "model"), false, ref model); GL.Uniform4(GL.GetUniformLocation(shader, "color"), Color); GL.BindVertexArray(_vao); GL.DrawElements(PrimitiveType.Triangles, _indicies.Length, DrawElementsType.UnsignedInt, 0); GL.BindVertexArray(0); } public void Update(double dt, Vector2d speed0) { Vector4 proper = Lorentz(speed0 - AbsSpeed) * new Vector4((float)dt, 0, 0, 0); Vector4 abs = Lorentz(-AbsSpeed) * new Vector4(proper.X, 0, 0, 0); InitialPosition += AbsSpeed * abs.X; } public Matrix4 GetTransform(double time0, Vector2d speed0) { Vector2d pos = InitialPosition + (AbsSpeed - speed0) * time0; return new Matrix4( 1, 0, 0, (float)time0, 0, (float)Scale.X, 0, (float)pos.X, 0, 0, (float)Scale.Y, (float)pos.Y, 0, 0, 0, 1); } public static Matrix4 Lorentz(Vector2d speed) { const double C = 1; Vector2d beta = speed / C; double lensq = beta.LengthSquared; double gamma = 1 / Math.Sqrt(1 - lensq); if (lensq == 0) return Matrix4.Identity; double Lxx = (gamma - 1) * beta.X * beta.X / lensq + 1; double Lyy = (gamma - 1) * beta.Y * beta.Y / lensq + 1; double Lxy = (gamma - 1) * beta.X * beta.Y / lensq; return new Matrix4( (float)gamma, (float)(-gamma * beta.X), (float)(-gamma * beta.Y), 0, (float)(-gamma * beta.X), (float)Lxx, (float)Lxy, 0, (float)(-gamma * beta.Y), (float)Lxy, (float)Lyy, 0, 0, 0, 0, 1 ); } private int _vbo, _vao, _ebo; private static readonly float[] _vertices = { -2.0f, 0.0f, 0.5f, 1.0f, -2.0f, -0.433f, -0.25f, 1.0f, -2.0f, 0.433f, -0.25f, 1.0f, 2.0f, 0.0f, 0.5f, 1.0f, 2.0f, -0.433f, -0.25f, 1.0f, 2.0f, 0.433f, -0.25f, 1.0f, }; private static readonly int[] _indicies = { 0, 1, 2, 0, 1, 4, 0, 4, 3, 1, 2, 5, 1, 5, 4, 2, 0, 3, 2, 3, 5, 3, 4, 5, }; private const int _stride = 4 * sizeof(float); } }