/// <summary>
        /// Construct the default ViewportState corresponding to a specific <see cref="GraphicsSurface"/>.
        /// </summary>
        /// <param name="graphicsSurface">
        /// The <see cref="GraphicsSurface"/> that specify tha default viewport extents.
        /// </param>
        public ViewportState(GraphicsSurface graphicsSurface)
        {
            if (graphicsSurface == null)
            {
                throw new ArgumentNullException("graphicsSurface");
            }

            Viewport = new Vertex4i(0, 0, (int)graphicsSurface.Width, (int)graphicsSurface.Height);
        }
        /// <summary>
        /// Construct a ViewportState representing the current viewport state.
        /// </summary>
        /// <param name="ctx">
        /// The <see cref="GraphicsContext"/> holding the viewport state.
        /// </param>
        public ViewportState(GraphicsContext ctx)
        {
            CheckCurrentContext(ctx);

            // Get current viewport
            int[] viewportCoords = new int[4];
            Gl.Get(Gl.VIEWPORT, viewportCoords);
            Viewport = new Vertex4i(viewportCoords[0], viewportCoords[1], viewportCoords[2], viewportCoords[3]);
        }
        public void TestUniform4i()
        {
            if (!HasVersion(2, 0) && !HasEsVersion(2, 0) && !IsGlExtensionSupported("GL_ARB_shader_objects"))
            {
                Assert.Inconclusive("required features not implemented");
            }

            using (Device device = new Device())
                using (new GLContext(device))
                {
                    uint program = CreateProgramUniform4i();

                    try {
                        Vertex4i uniformStruct;
                        int[]    uniformValue;

                        int uniformLoc = Gl.GetUniformLocation(program, "uVec");
                        if (uniformLoc < 0)
                        {
                            throw new InvalidOperationException("no uniform variable");
                        }

                        // glGetUniformiv
                        uniformValue = Array4(1);
                        Gl.GetUniform(program, uniformLoc, uniformValue);
                        CollectionAssert.AreEqual(Array4(0), uniformValue);

                        // glGetUniformiv (ref)
                        uniformStruct = new Vertex4i(1);
                        Gl.GetUniformi(program, uniformLoc, ref uniformStruct);
                        Assert.AreEqual(Vertex4i.Zero, uniformStruct);

                        // glUniform4i
                        uniformValue = Array4(0);
                        Gl.Uniform4(uniformLoc, Array4(1));
                        Gl.GetUniform(program, uniformLoc, uniformValue);
                        CollectionAssert.AreEqual(Array4(1), uniformValue);

                        // glUniform4iv
                        uniformValue = Array4(0);
                        Gl.Uniform4(uniformLoc, Array4(9));
                        Gl.GetUniform(program, uniformLoc, uniformValue);
                        CollectionAssert.AreEqual(Array4(9), uniformValue);

                        // glUniform4iv (ref)
                        uniformValue  = Array4(0);
                        uniformStruct = new Vertex4i(5);
                        Gl.Uniform4i(uniformLoc, 1, ref uniformStruct);
                        Gl.GetUniform(program, uniformLoc, uniformValue);
                        CollectionAssert.AreEqual(Array4(5), uniformValue);
                    } finally {
                        Gl.DeleteProgram(program);
                    }
                }
        }
        /// <summary>
        /// Merge this state with another one.
        /// </summary>
        /// <param name="state">
        /// A <see cref="IGraphicsState"/> having the same <see cref="GraphicsState.StateIdentifier"/> of this state.
        /// </param>
        /// <remarks>
        /// <para>
        /// After a call to this routine, this IGraphicsState store the union of the previous information
        /// and of the information of <paramref name="state"/>.
        /// </para>
        /// <para>
        /// The semantic of the merge result is dependent on the actual implementation of this IGraphicsState. Normally
        /// the merge method will copy <paramref name="state"/> into this IGraphicsState, but other state could do
        /// different operations.
        /// </para>
        /// </remarks>
        public override void Merge(IGraphicsState state)
        {
            if (state == null)
            {
                throw new ArgumentNullException("state");
            }
            if (state.StateIdentifier != StateId)
            {
                throw new ArgumentException("state id mismatch", "state");
            }

            ViewportState previousState = (ViewportState)state;

            Viewport = previousState.Viewport;
        }
 void IShaderUniformContainer.SetUniform(GraphicsContext ctx, string uniformName, Vertex4i v)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Construct a ViewportState specifing the width and the height of the viewport.
 /// </summary>
 /// <param name="width">
 /// A <see cref="Int32"/> that specify the width of the viewport.
 /// </param>
 /// <param name="height">
 /// A <see cref="Int32"/> that specify the height of the viewport.
 /// </param>
 public ViewportState(int width, int height)
 {
     Viewport = new Vertex4i(0, 0, width, height);
 }
		/// <summary>
		/// Set uniform state variable (ivec4 variable or bvec4 variable).
		/// </summary>
		/// <param name="ctx">
		/// A <see cref="GraphicsContext"/> used for operations.
		/// </param>
		/// <param name="uniformName">
		/// A <see cref="String"/> that specify the variable name in the shader source.
		/// </param>
		/// <param name="v">
		/// A <see cref="Vertex4i"/> holding the uniform variabile data (first component).
		/// </param>
		public void SetUniform(GraphicsContext ctx, string uniformName, Vertex4i v)
		{
			SetUniform(ctx, uniformName, v.x, v.y, v.z, v.w);
		}