/// <summary>Function called to initialize the effect.</summary>
        /// <remarks>Applications must implement this method to ensure that any required resources are created, and configured for the effect.</remarks>
        protected override void OnInitialize()
        {
            // Initialize the default look up table.
            using (IGorgonImage image = new GorgonImage(new GorgonImageInfo(ImageType.Image1D, BufferFormat.R8G8B8A8_UNorm)
            {
                Width = 3
            }))
            {
                image.ImageData.ReadAs <int>(0) = GorgonColor.RedPure.ToABGR();
                image.ImageData.ReadAs <int>(4) = GorgonColor.BluePure.ToABGR();
                image.ImageData.ReadAs <int>(8) = GorgonColor.GreenPure.ToABGR();

                _defaultLut = GorgonTexture1DView.CreateTexture(Graphics, new GorgonTexture1DInfo("Default Spectral LUT")
                {
                    Binding = TextureBinding.ShaderResource,
                    Usage   = ResourceUsage.Immutable,
                    Width   = 3
                }, image);
            }

            _chromeAbShader       = GorgonShaderFactory.Compile <GorgonPixelShader>(Graphics, Resources.ChromaticAberration, "ChromaticAberration", GorgonGraphics.IsDebugEnabled);
            _simpleChromeAbShader = GorgonShaderFactory.Compile <GorgonPixelShader>(Graphics, Resources.ChromaticAberration, "ChromaticAberrationSimple", GorgonGraphics.IsDebugEnabled);

            _settings = GorgonConstantBufferView.CreateConstantBuffer(Graphics, new GorgonConstantBufferInfo("Chromatic Aberration Settings Buffer")
            {
                SizeInBytes = DX.Vector4.SizeInBytes,
                Usage       = ResourceUsage.Default
            });
        }
        /// <summary>Releases unmanaged and - optionally - managed resources.</summary>
        /// <param name="disposing">
        ///   <c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            GorgonTexture1DView      texture = Interlocked.Exchange(ref _defaultLut, null);
            GorgonPixelShader        shader1 = Interlocked.Exchange(ref _chromeAbShader, null);
            GorgonPixelShader        shader2 = Interlocked.Exchange(ref _simpleChromeAbShader, null);
            GorgonConstantBufferView cbv     = Interlocked.Exchange(ref _settings, null);

            shader1?.Dispose();
            shader2?.Dispose();
            texture?.Dispose();
            cbv?.Dispose();
        }
        /// <summary>Function called to build a new (or return an existing) 2D batch state.</summary>
        /// <param name="passIndex">The index of the current rendering pass.</param>
        /// <param name="statesChanged">
        ///   <b>true</b> if the blend, raster, or depth/stencil state was changed. <b>false</b> if not.</param>
        /// <returns>The 2D batch state.</returns>
        protected override Gorgon2DBatchState OnGetBatchState(int passIndex, bool statesChanged)
        {
            if ((_useSimple != FullScreen) ||
                ((LookupTexture == null) && (_currentLut != _defaultLut)) ||
                ((LookupTexture != null) && (LookupTexture != _currentLut)))
            {
                GorgonPixelShader current = FullScreen ? _simpleChromeAbShader : _chromeAbShader;
                _currentLut = LookupTexture ?? _defaultLut;

                _chromeAbBatchState = BatchStateBuilder.Clear()
                                      .BlendState(GorgonBlendState.NoBlending)
                                      .PixelShaderState(_shaderStateBuilder
                                                        .Clear()
                                                        .Shader(current)
                                                        .ShaderResource(!FullScreen ? _currentLut : null, 1)
                                                        .SamplerState(!FullScreen ? GorgonSamplerState.Default : null, 1)
                                                        .ConstantBuffer(_settings, 1))
                                      .Build();

                _useSimple = FullScreen;
            }

            return(_chromeAbBatchState);
        }