/// <summary> This sets the GL state variables to the render state this object requires. Called by RenderableItem</summary>
        public void ApplyState(GLRenderState newstate)      // apply deltas to GL
        {
            // general

            //System.Diagnostics.Debug.WriteLine("Apply " + newstate.PrimitiveType + " Fixed state " + newstate.ApplyFixed);

            if (newstate.PrimitiveRestart != PrimitiveRestart)
            {
                //System.Diagnostics.Debug.WriteLine("Set PR to {0}", newstate.PrimitiveRestart);
                if (newstate.PrimitiveRestart.HasValue)        // is new state has value
                {
                    if (PrimitiveRestart == null)              // if last was off, turn it on
                    {
                        GL.Enable(EnableCap.PrimitiveRestart);
                    }

                    GL.PrimitiveRestartIndex(newstate.PrimitiveRestart.Value);  // set
                }
                else
                {
                    GL.Disable(EnableCap.PrimitiveRestart);     // else disable
                }
                PrimitiveRestart = newstate.PrimitiveRestart;
            }

            if (ClipDistanceEnable != newstate.ClipDistanceEnable)        // if changed
            {
                if (newstate.ClipDistanceEnable > ClipDistanceEnable)
                {
                    for (int i = ClipDistanceEnable; i < newstate.ClipDistanceEnable; i++)
                    {
                        GL.Enable(EnableCap.ClipDistance0 + i);
                    }
                }
                else if (newstate.ClipDistanceEnable < ClipDistanceEnable)
                {
                    for (int i = ClipDistanceEnable - 1; i >= newstate.ClipDistanceEnable; i--)
                    {
                        GL.Disable(EnableCap.ClipDistance0 + i);
                    }
                }

                ClipDistanceEnable = newstate.ClipDistanceEnable;
            }

            if (DepthTest != newstate.DepthTest)
            {
                DepthTest = newstate.DepthTest;
                GLStatics.SetEnable(OpenTK.Graphics.OpenGL.EnableCap.DepthTest, DepthTest);
                //  System.Diagnostics.Debug.WriteLine("Depth Test " + DepthTest);
            }

            if (DepthFunctionMode != newstate.DepthFunctionMode)
            {
                DepthFunctionMode = newstate.DepthFunctionMode;
                GL.DepthFunc(DepthFunctionMode);
            }

            if (WriteDepthBuffer != newstate.WriteDepthBuffer)
            {
                WriteDepthBuffer = newstate.WriteDepthBuffer;
                GL.DepthMask(WriteDepthBuffer);
            }

            if (DepthClamp != newstate.DepthClamp)
            {
                DepthClamp = newstate.DepthClamp;
                GLStatics.SetEnable(OpenTK.Graphics.OpenGL.EnableCap.DepthClamp, DepthClamp);
                // System.Diagnostics.Debug.WriteLine("Depth Clamp" + DepthClamp.Value);
            }

            if (BlendEnable != newstate.BlendEnable)
            {
                BlendEnable = newstate.BlendEnable;
                GLStatics.SetEnable(OpenTK.Graphics.OpenGL.EnableCap.Blend, BlendEnable);
            }

            // blend on, we have new values for blend equation
            if (BlendEnable == true)
            {
                if (BlendSourceRGB != newstate.BlendSourceRGB || BlendDestRGB != newstate.BlendDestRGB ||
                    BlendSourceA != newstate.BlendSourceA || BlendDestA != newstate.BlendDestA)
                {
                    BlendSourceRGB = newstate.BlendSourceRGB;
                    BlendDestRGB   = newstate.BlendDestRGB;
                    BlendSourceA   = newstate.BlendSourceA;
                    BlendDestA     = newstate.BlendDestA;
                    GL.BlendFuncSeparate(BlendSourceRGB, BlendDestRGB, BlendSourceA, BlendDestA);
                }

                if (BlendEquationRGB != newstate.BlendEquationRGB || BlendEquationA != newstate.BlendEquationA)
                {
                    BlendEquationRGB = newstate.BlendEquationRGB;
                    BlendEquationA   = newstate.BlendEquationA;
                    GL.BlendEquationSeparate(BlendEquationRGB, BlendEquationA);
                }
            }

            if (ColorMasking != newstate.ColorMasking)
            {
                ColorMasking = newstate.ColorMasking;

                GL.ColorMask((ColorMasking & ColorMask.Red) == ColorMask.Red, (ColorMasking & ColorMask.Green) == ColorMask.Green,
                             (ColorMasking & ColorMask.Blue) == ColorMask.Blue, (ColorMasking & ColorMask.Alpha) == ColorMask.Alpha);
            }

            if (newstate.Discard != Discard)
            {
                Discard = newstate.Discard;
                GLStatics.SetEnable(OpenTK.Graphics.OpenGL.EnableCap.RasterizerDiscard, Discard);
                //System.Diagnostics.Debug.WriteLine("RS Discard " + Discard);
            }

            // ---------------------------------- Below are default null

            // Geo shaders

            if (newstate.PatchSize.HasValue && PatchSize != newstate.PatchSize)
            {
                PatchSize = newstate.PatchSize;
                GL.PatchParameter(PatchParameterInt.PatchVertices, PatchSize.Value);
            }

            // points

            if (newstate.PointSize.HasValue && PointSize != newstate.PointSize)
            {
                if (newstate.PointSize > 0)     // if fixed point size
                {
                    if (PointSize == null || newstate.PointSize != PointSize.Value)
                    {
                        GL.PointSize(newstate.PointSize.Value); // set if different
                    }
                    if (PointSize == null || PointSize == 0)    // if previous was off
                    {
                        GL.Disable(EnableCap.ProgramPointSize);
                    }
                }
                else
                {
                    GL.Enable(EnableCap.ProgramPointSize);
                }

                PointSize = newstate.PointSize;
            }

            if (newstate.PointSprite.HasValue && PointSprite != newstate.PointSprite)
            {
                PointSprite = newstate.PointSprite;
                GLStatics.SetEnable(OpenTK.Graphics.OpenGL.EnableCap.PointSprite, PointSprite.Value);
            }

            if (newstate.PointSmooth.HasValue && PointSmooth != newstate.PointSmooth)
            {
                PointSmooth = newstate.PointSmooth;
                GLStatics.SetEnable(OpenTK.Graphics.OpenGL.EnableCap.PointSmooth, PointSmooth.Value);
            }

            // lines

            if (newstate.LineWidth.HasValue && LineWidth != newstate.LineWidth)
            {
                LineWidth = newstate.LineWidth;
                GL.LineWidth(LineWidth.Value);
            }

            if (newstate.LineSmooth.HasValue && LineSmooth != newstate.LineSmooth)
            {
                LineSmooth = newstate.LineSmooth;
                GLStatics.SetEnable(OpenTK.Graphics.OpenGL.EnableCap.LineSmooth, LineSmooth.Value);
            }

            // triangles

            if (newstate.PolygonModeFrontAndBack.HasValue && PolygonModeFrontAndBack != newstate.PolygonModeFrontAndBack)
            {
                PolygonModeFrontAndBack = newstate.PolygonModeFrontAndBack;
                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonModeFrontAndBack.Value);
            }

            if (newstate.PolygonSmooth.HasValue && PolygonSmooth != newstate.PolygonSmooth)
            {
                PolygonSmooth = newstate.PolygonSmooth;
                GLStatics.SetEnable(OpenTK.Graphics.OpenGL.EnableCap.PolygonSmooth, PolygonSmooth.Value);
            }

            if (newstate.CullFace.HasValue && CullFace != newstate.CullFace)
            {
                CullFace = newstate.CullFace;
                GLStatics.SetEnable(OpenTK.Graphics.OpenGL.EnableCap.CullFace, CullFace.Value);
                // System.Diagnostics.Debug.WriteLine("Cull mode " + CullFace.Value);
            }

            if (newstate.FrontFace.HasValue && FrontFace != newstate.FrontFace)
            {
                FrontFace = newstate.FrontFace;
                GL.FrontFace(FrontFace.Value);
            }
        }