/// <summary>
        /// Attaches a color buffer to the render target.
        /// </summary>
        /// <param name="buffer">The color buffer to attach to the render target.</param>
        private void AttachColorBuffer(OpenGLRenderBuffer2D buffer)
        {
            Contract.Ensure(colorAttachments < 16, OpenGLStrings.RenderBufferExceedsTargetCapacity);

            if (colorAttachments > 0 && buffer.SrgbEncoded != hasSrgbEncodedColorBuffer)
            {
                throw new InvalidOperationException(UltravioletStrings.TargetsCannotHaveMultipleEncodings);
            }

            hasSrgbEncodedColorBuffer = buffer.SrgbEncoded;

            if (buffer.WillNotBeSampled)
            {
                gl.NamedFramebufferRenderbuffer(framebuffer, gl.GL_FRAMEBUFFER,
                                                (uint)(gl.GL_COLOR_ATTACHMENT0 + colorAttachments), gl.GL_RENDERBUFFER, buffer.OpenGLName);
                gl.ThrowIfError();
            }
            else
            {
                if (!gl.IsFramebufferTextureAvailable)
                {
                    gl.FramebufferTexture2D(gl.GL_FRAMEBUFFER,
                                            (uint)(gl.GL_COLOR_ATTACHMENT0 + colorAttachments), gl.GL_TEXTURE_2D, buffer.OpenGLName, 0);
                    gl.ThrowIfError();
                }
                else
                {
                    gl.NamedFramebufferTexture(framebuffer, gl.GL_FRAMEBUFFER,
                                               (uint)(gl.GL_COLOR_ATTACHMENT0 + colorAttachments), buffer.OpenGLName, 0);
                    gl.ThrowIfError();
                }
            }

            colorAttachments++;
        }
        /// <summary>
        /// Attaches a stencil buffer to the render target.
        /// </summary>
        /// <param name="buffer">The stencil buffer to attach to the render target.</param>
        private void AttachStencilBuffer(OpenGLRenderBuffer2D buffer)
        {
            Contract.Ensure(stencilAttachments == 0 && depthStencilAttachments == 0, OpenGLStrings.RenderBufferExceedsTargetCapacity);

            if (buffer.WillNotBeSampled)
            {
                gl.NamedFramebufferRenderbuffer(framebuffer, gl.GL_FRAMEBUFFER, gl.GL_STENCIL_ATTACHMENT, gl.GL_RENDERBUFFER, buffer.OpenGLName);
                gl.ThrowIfError();
            }
            else
            {
                if (!gl.IsFramebufferTextureAvailable)
                {
                    gl.FramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_STENCIL_ATTACHMENT, gl.GL_TEXTURE_2D, buffer.OpenGLName, 0);
                    gl.ThrowIfError();
                }
                else
                {
                    gl.NamedFramebufferTexture(framebuffer, gl.GL_FRAMEBUFFER, gl.GL_STENCIL_ATTACHMENT, buffer.OpenGLName, 0);
                    gl.ThrowIfError();
                }
            }

            stencilAttachments++;
        }
        /// <summary>
        /// Attaches a render buffer to the render target.
        /// </summary>
        /// <param name="buffer">The render buffer to attach to the render target.</param>
        private void AttachRenderBuffer(OpenGLRenderBuffer2D buffer)
        {
            switch (buffer.Format)
            {
            case RenderBufferFormat.Color:
                AttachColorBuffer(buffer);
                break;

            case RenderBufferFormat.Depth32:
            case RenderBufferFormat.Depth16:
                AttachDepthBuffer(buffer);
                break;

            case RenderBufferFormat.Stencil8:
                AttachStencilBuffer(buffer);
                break;

            case RenderBufferFormat.Depth24Stencil8:
                AttachDepthStencilBuffer(buffer);
                break;

            default:
                throw new NotSupportedException();
            }

            UpdateDrawBuffers();
        }