/// <summary>
        /// Draws the actual diffusion to the buffer, and overlays a full screen texture on the viewport.
        /// </summary>
        public int DrawDiffusion()
        {
            if (buffers.ListPathPoints.Count == 0)
            {
                return(-1);
            }

            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, FBOHandle);
            GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, colorTexturePing, 0);
            GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.DepthAttachmentExt, TextureTarget.Texture2D, depthTexture, 0);

            CheckFrameBufferStatus();

            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            DrawBezierCurves();
            DrawEndPoints();

            GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.DepthAttachmentExt, TextureTarget.Texture2D, 0, 0);

            int currentColorTexture = colorTexturePing;
            int currentColorBuffer  = colorTexturePong;

            GL.UseProgram(diffuseShader.ShaderProgramHandle);
            diffuseShader.EnableAttributes();
            diffuseShader.BindTexture(ref depthTexture, TextureUnit.Texture1, "depth_texture");
            int   width  = renderState.ViewSize.Width;
            int   height = renderState.ViewSize.Height;
            float scale  = (float)Math.Sqrt(width * width + height * height);

            GL.Uniform1(GL.GetUniformLocation(diffuseShader.ShaderProgramHandle, "xScale"), (scale - 1f) / width);
            GL.Uniform1(GL.GetUniformLocation(diffuseShader.ShaderProgramHandle, "yScale"), (scale - 1f) / height);
            for (int i = 0; i < iterations; i++)
            {
                GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, currentColorBuffer, 0);
                CheckFrameBufferStatus();

                GL.ClearColor(Color.Black);
                GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

                GL.Uniform1(GL.GetUniformLocation(diffuseShader.ShaderProgramHandle, "iteration"), i + 1);
                diffuseShader.BindTexture(ref currentColorTexture, TextureUnit.Texture0, "color_texture");
                DrawTexturedQuad(-1, 1, 1, -1, diffuseShader);

                int tempColorTexture = currentColorTexture;
                currentColorTexture = currentColorBuffer;
                currentColorBuffer  = tempColorTexture;
            }
            diffuseShader.DisableAttributes();

            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);

            return(currentColorTexture);
        }
        /// <summary>
        /// The main draw call to draw the current frame
        /// </summary>
        public void Draw()
        {
            GL.ClearColor(Color.Gray);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();

            GL.Disable(EnableCap.DepthTest);
            DrawBackground();
            DrawImage();

            if (drawDiffusion)
            {
                GL.Enable(EnableCap.DepthTest);
                int tex = DrawDiffusion();
                if (GL.IsTexture(tex))
                {
                    GL.UseProgram(imageShader.ShaderProgramHandle);
                    imageShader.SetProjectionMatrix(Matrix4.Identity);
                    imageShader.EnableAttributes();
                    imageShader.BindTexture(ref tex, TextureUnit.Texture0, "background");

                    DrawTexturedQuad(-1, 1, 1, -1, imageShader);
                    imageShader.DisableAttributes();
                    imageShader.SetProjectionMatrix(renderState.ProjectionMatrix);
                }
                GL.Disable(EnableCap.DepthTest);
            }

            DrawBezierLines();
            DrawControlLines();
            DrawPoints();
            GL.Enable(EnableCap.DepthTest);

            if (GL.GetError() != ErrorCode.NoError)
            {
                Debug.WriteLine(GL.GetError().ToString());
            }
        }