protected override void OnLoad(EventArgs args)
        {
            base.OnLoad (args);
            GL.Viewport(0, 0, Width, Height);

            GL.ClearColor (0.0f, 0.0f, 0.0f,0.0f);
            GL.Enable (EnableCap.DepthTest);
            GL.Enable (EnableCap.Blend);
            GL.BlendFunc (BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
            GL.PointSize(2.5f);
            VSync = OpenTK.VSyncMode.Off;
            InitProgram ();

            model = new IMatrixStack ();
            view = new IMatrix ();
            proj = new IMatrix ();
            Reset ();
            ResetTrackBall ();
            useColor = false;

            Keyboard.KeyDown += (s, e) => {
                switch(e.Key){
                    case Key.W:
                    {
                        wireframeOn = !wireframeOn;
                        break;
                    }
                case Key.S:
                    {
                        if (appliedForce)
                            break;
                        cloth.ApplyForce (clothForce);
                        appliedForce = true;
                        break;
                    }
                case Key.T:
                {
                    useLines = !useLines;
                    break;
                }
                case Key.R:
                    {
                        Reset ();
                        break;
                    }
                case Key.X:
                        {
                            ResetTrackBall ();
                            break;
                        }
                case Key.P:
                    {
                        pause = !pause;
                        break;
                    }
                case Key.A:
                    {
                        animateSphere=!animateSphere;
                        break;
                    }
                case Key.C:
                {
                    useColor = !useColor;
                    Console.WriteLine("using color");
                    break;
                }
                case Key.Number1:
                    {
                    Reset();
                        Type1();
                        break;
                    }
                case Key.Number2:
                    {
                    Reset();
                        Type2();
                        break;
                    }
                case Key.Number3:
                    {
                    Reset();
                    Type3();

                        break;
                    }
                case Key.Number4:
                {
                    Reset();
                    Type4();

                    break;
                }
                case Key.Number5:
                {
                    Reset();
                    Type5();

                    break;
                }
                case Key.Number6:
                {
                    Reset();
                    Type6();

                    break;
                }
                }

            };
        }
 public void MultMatrix(IMatrix im)
 {
     stack.Push(Top().Dot(im));
 }
        protected override void OnRenderFrame(OpenTK.FrameEventArgs e)
        {
            base.OnRenderFrame (e);

            GL.Clear (ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            if (wireframeOn)
                GL.PolygonMode (MaterialFace.FrontAndBack, PolygonMode.Line);
            else
                GL.PolygonMode (MaterialFace.FrontAndBack, PolygonMode.Fill);

            proj = new IMatrix();

            float aspectRatio = (float) ((1.0f * this.Width) / this.Height);

            //fixing aspect ratio
            if (aspectRatio < 1.0)
                proj = IMatrix.Scaling(1.0f, aspectRatio, 0.5f);
            else
                proj = IMatrix.Scaling(1/aspectRatio,1, 0.5f);

            //perspective
            proj = proj.Dot(IMatrix.Perspective (1.0f, 0.2f, 20.0f));

            //view
            view = trackball.InvertibleTransform ();

            model.SetIdentity ();
            //from now on... model!
            foreach (var sphere in spheres) {

                model.Push ();
                model.MultMatrix (sphere.Model);

                SendUniforms (sphere.Color);
                DrawSphere (sphere.Radius, sphere.Rings, sphere.Segments);
                model.Pop ();
            }

            foreach (var capsule in capsules) {
                DrawCapsule1 (capsule);
            }

            model.Push ();
            model.MultMatrix (cloth.Model);
            SendUniforms (new Vec4(0.5f,1,0.3f,1.0f));
            DrawMesh (cloth);
            model.Pop ();

            SwapBuffers ();
            var N = 10;
            for (var i = 0; i<N; i++) {
                doPhysics ((float)e.Time/N);
            }
        }
 public IMatrix Dot(IMatrix im)
 {
     return new IMatrix(Direct.Dot(im.Direct), im.Inverse.Dot(Inverse));
 }