/// <summary>
        /// Begins a new sprite batch using the appropriate settings for rendering UPF.
        /// </summary>
        /// <param name="sortMode">The sorting mode to use when rendering interface elements.</param>
        /// <param name="blendState">The blend state to apply to the rendered elements.</param>
        /// <param name="samplerState">The sampler state to apply to the rendered interface elements.</param>
        /// <param name="effect">The custom effect to apply to the rendered interface elements.</param>
        /// <param name="localTransform">The transform matrix to apply to the rendered interface elements.</param>
        public void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, Effect effect, Matrix localTransform)
        {
            if (SpriteBatch == null)
                throw new InvalidOperationException(PresentationStrings.DrawingContextDoesNotHaveSpriteBatch);

            this.localTransform = localTransform;
            this.combinedTransform = Matrix.Identity;
            Matrix.Concat(ref localTransform, ref globalTransform, out combinedTransform);

            SpriteBatch.Begin(sortMode, 
                blendState ?? BlendState.AlphaBlend,
                samplerState ?? SamplerState.LinearClamp, 
                StencilReadDepthState, RasterizerState.CullCounterClockwise, effect, combinedTransform);
        }
 /// <inheritdoc/>
 public void SetSamplerState(Int32 sampler, SamplerState state)
 {
     Contract.EnsureNotDisposed(this, Disposed);
 }
        /// <inheritdoc/>
        public void SetSamplerState(Int32 sampler, SamplerState state)
        {
            Contract.EnsureRange(sampler >= 0 && sampler < maxTextureStages, nameof(sampler));
            Contract.Require(state, nameof(state));
            Contract.EnsureNotDisposed(this, Disposed);

            Ultraviolet.ValidateResource(state);

            var oglstate = (OpenGLSamplerState)state;

            if (this.samplerStates[sampler] != state)
            {
                if (capabilities.SupportsIndependentSamplerState)
                {
                    var samplerObject = this.samplerObjects[sampler];
                    samplerObject.ApplySamplerState(state);
                }
                else
                {
                    oglstate.Apply(sampler);
                    this.samplerStates[sampler] = state;

                    var texture = this.textures[sampler];
                    if (texture != null)
                    {
                        for (int i = 0; i < samplerStates.Length; i++)
                        {
                            if (i == sampler)
                                continue;

                            if (this.textures[i] == texture && this.samplerStates[i] != oglstate)
                            {
                                oglstate.Apply(sampler);
                                this.samplerStates[sampler] = state;
                            }
                        }
                    }
                }
            }
        }
        /// <inheritdoc/>
        public void SetSamplerState(Int32 sampler, SamplerState state)
        {
            Contract.EnsureRange(sampler >= 0 && sampler < maxTextureStages, "sampler");
            Contract.Require(state, "state");
            Contract.EnsureNotDisposed(this, Disposed);

            Ultraviolet.ValidateResource(state);

            if (this.samplerStates[sampler] != state)
            {
                ((OpenGLSamplerState)state).Apply(sampler);
                this.samplerStates[sampler] = state;
            }
        }
        /// <summary>
        /// Applies the specified sampler state to this sampler.
        /// </summary>
        /// <param name="state">The sampler state to apply.</param>
        public void ApplySamplerState(SamplerState state)
        {
            Contract.Require(state, nameof(state));

            gl.SamplerParameteri(sampler, gl.GL_TEXTURE_WRAP_S, OpenGLSamplerState.GetTextureAddressModeGL(state.AddressU));
            gl.ThrowIfError();

            gl.SamplerParameteri(sampler, gl.GL_TEXTURE_WRAP_T, OpenGLSamplerState.GetTextureAddressModeGL(state.AddressV));
            gl.ThrowIfError();

            if (gl.IsGLES)
            {
                if (state.MipMapLevelOfDetailBias != 0)
                    throw new NotSupportedException(OpenGLStrings.UnsupportedLODBiasGLES);
            }
            else
            {
                gl.SamplerParameterf(sampler, gl.GL_TEXTURE_LOD_BIAS, state.MipMapLevelOfDetailBias);
                gl.ThrowIfError();
            }

            switch (state.Filter)
            {
                case TextureFilter.Point:
                    gl.SamplerParameterf(sampler, gl.GL_TEXTURE_MAX_ANISOTROPY_EXT, 1f);
                    gl.ThrowIfError();

                    gl.SamplerParameterf(sampler, gl.GL_TEXTURE_MIN_FILTER, (int)gl.GL_NEAREST);
                    gl.ThrowIfError();

                    gl.SamplerParameterf(sampler, gl.GL_TEXTURE_MAG_FILTER, (int)gl.GL_NEAREST);
                    gl.ThrowIfError();
                    break;

                case TextureFilter.Linear:
                    if (gl.IsAnisotropicFilteringAvailable)
                    {
                        gl.SamplerParameterf(sampler, gl.GL_TEXTURE_MAX_ANISOTROPY_EXT, 1f);
                        gl.ThrowIfError();
                    }

                    gl.SamplerParameteri(sampler, gl.GL_TEXTURE_MIN_FILTER, (int)gl.GL_LINEAR);
                    gl.ThrowIfError();

                    gl.SamplerParameteri(sampler, gl.GL_TEXTURE_MAG_FILTER, (int)gl.GL_LINEAR);
                    gl.ThrowIfError();
                    break;

                case TextureFilter.Anisotropic:
                    if (gl.IsAnisotropicFilteringAvailable)
                    {
                        gl.SamplerParameterf(sampler, gl.GL_TEXTURE_MAX_ANISOTROPY_EXT, Math.Min(1f, state.MaxAnisotropy));
                        gl.ThrowIfError();
                    }

                    gl.SamplerParameteri(sampler, gl.GL_TEXTURE_MIN_FILTER, (int)gl.GL_LINEAR);
                    gl.ThrowIfError();

                    gl.SamplerParameteri(sampler, gl.GL_TEXTURE_MAG_FILTER, (int)gl.GL_LINEAR);
                    gl.ThrowIfError();
                    break;

                default:
                    throw new NotSupportedException();
            }
        }