using CMLeonOS; using CMLeonOS.Gui.UILib; using CMLeonOS.OSGraphicDraw; using System; using System.Drawing; namespace CMLeonOS.Gui.Apps.Demos { internal class GLXGears : Process { internal GLXGears() : base("GLXGears", ProcessType.Application) { } private readonly WindowManager wm = ProcessManager.GetProcess(); private AppWindow window; private double redAngle = 0d; private double greenAngle = 0d; private double blueAngle = 0d; private int fps = 0; private int frames = 0; private int lastSecond = -1; private const double ScenePitch = 0.48d; private const double SceneYaw = -0.36d; private const double FovScale = 260d; private const double CameraDistance = 10.5d; private Vec3 TransformPoint(Vec3 p) { p = Vec3.RotateX(p, ScenePitch); p = Vec3.RotateY(p, SceneYaw); return p; } private void Draw3DLine(Vec3 a, Vec3 b, Color color) { a = TransformPoint(a); b = TransformPoint(b); Renderer3D.DrawLine3D(window, a, b, color, FovScale, CameraDistance); } private void Draw3DTriangle(Vec3 a, Vec3 b, Vec3 c, Color color) { a = TransformPoint(a); b = TransformPoint(b); c = TransformPoint(c); Renderer3D.DrawTriangle3D(window, a, b, c, color, FovScale, CameraDistance); } private void DrawGear(Vec3 center, double outerRadius, double innerRadius, double depth, int teeth, double angle, Color color) { int ringCount = teeth * 2; Vec3[] frontOuter = new Vec3[ringCount]; Vec3[] backOuter = new Vec3[ringCount]; Vec3[] frontInner = new Vec3[ringCount]; Vec3[] backInner = new Vec3[ringCount]; double frontZ = center.Z + (depth * 0.5d); double backZ = center.Z - (depth * 0.5d); for (int i = 0; i < ringCount; i++) { bool tooth = (i % 2) == 0; double radius = tooth ? outerRadius : outerRadius * 0.84d; double t = (i / (double)ringCount) * (Math.PI * 2d) + angle; double c = Math.Cos(t); double s = Math.Sin(t); frontOuter[i] = new Vec3(center.X + (radius * c), center.Y + (radius * s), frontZ); backOuter[i] = new Vec3(center.X + (radius * c), center.Y + (radius * s), backZ); frontInner[i] = new Vec3(center.X + (innerRadius * c), center.Y + (innerRadius * s), frontZ); backInner[i] = new Vec3(center.X + (innerRadius * c), center.Y + (innerRadius * s), backZ); } for (int i = 0; i < ringCount; i++) { int n = (i + 1) % ringCount; Color frontFace = Color.FromArgb( color.R, color.G, color.B); Color backFace = Color.FromArgb( Math.Max(0, color.R - 32), Math.Max(0, color.G - 32), Math.Max(0, color.B - 32)); Color sideFace = Color.FromArgb( Math.Max(0, color.R - 18), Math.Max(0, color.G - 18), Math.Max(0, color.B - 18)); // Front ring face (quad -> 2 triangles) Draw3DTriangle(frontOuter[i], frontOuter[n], frontInner[n], frontFace); Draw3DTriangle(frontOuter[i], frontInner[n], frontInner[i], frontFace); // Back ring face Draw3DTriangle(backOuter[i], backInner[n], backOuter[n], backFace); Draw3DTriangle(backOuter[i], backInner[i], backInner[n], backFace); // Outer wall Draw3DTriangle(frontOuter[i], backOuter[n], frontOuter[n], sideFace); Draw3DTriangle(frontOuter[i], backOuter[i], backOuter[n], sideFace); // Inner wall Draw3DTriangle(frontInner[i], frontInner[n], backInner[n], sideFace); Draw3DTriangle(frontInner[i], backInner[n], backInner[i], sideFace); Draw3DLine(frontOuter[i], frontOuter[n], color); Draw3DLine(backOuter[i], backOuter[n], color); Draw3DLine(frontOuter[i], backOuter[i], color); Draw3DLine(frontInner[i], frontInner[n], color); Draw3DLine(backInner[i], backInner[n], color); Draw3DLine(frontInner[i], backInner[i], color); if ((i % 2) == 0) { Draw3DLine(frontOuter[i], frontInner[i], color); Draw3DLine(backOuter[i], backInner[i], color); } } } private void RenderGears() { window.Clear(Color.FromArgb(14, 16, 23)); DrawGear(new Vec3(-2.6d, -0.8d, 0.0d), 1.85d, 0.72d, 0.75d, 20, redAngle, Color.FromArgb(238, 95, 95)); DrawGear(new Vec3(2.35d, -0.95d, 0.0d), 1.65d, 0.66d, 0.75d, 18, greenAngle, Color.FromArgb(108, 214, 132)); DrawGear(new Vec3(0.25d, 2.0d, 0.0d), 1.45d, 0.58d, 0.75d, 16, blueAngle, Color.FromArgb(113, 170, 255)); window.DrawString("OSGD GLXGears", Color.FromArgb(182, 194, 214), 10, 8); window.DrawString("FPS: " + fps.ToString(), Color.FromArgb(182, 194, 214), 10, 26); wm.Update(window); } public override void Start() { base.Start(); window = new AppWindow(this, 220, 120, 620, 420); window.Title = "GLXGears"; window.CanResize = true; window.Closing = TryStop; wm.AddWindow(window); RenderGears(); } public override void Run() { redAngle += 0.055d; greenAngle -= 0.082d; blueAngle += 0.105d; DateTime now = DateTime.Now; frames++; if (lastSecond != now.Second) { fps = frames; frames = 0; lastSecond = now.Second; } RenderGears(); } } }