Exemplo n.º 1
0
        /// <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)
        {
            if (!disposing)
            {
                return;
            }

            GorgonVertexShader       vertexShader   = Interlocked.Exchange(ref _vertexDeferShader, null);
            GorgonPixelShader        deferredShader = Interlocked.Exchange(ref _pixelDeferShader, null);
            GorgonPixelShader        lightShader    = Interlocked.Exchange(ref _pixelLitShader, null);
            GorgonConstantBufferView lightData      = Interlocked.Exchange(ref _lightData, null);
            GorgonConstantBufferView globalData     = Interlocked.Exchange(ref _globalData, null);

            GorgonRenderTargetView[] targets     = Interlocked.Exchange(ref _gbufferTargets, null);
            GorgonTexture2DView      textureView = Interlocked.Exchange(ref _gbufferTexture, null);

            textureView?.Dispose();

            for (int i = 0; i < targets.Length; ++i)
            {
                targets[i]?.Dispose();
            }

            globalData?.Dispose();
            lightData?.Dispose();
            lightShader?.Dispose();
            deferredShader?.Dispose();
            vertexShader?.Dispose();
        }
        /// <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
            });
        }
Exemplo n.º 3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CameraController"/> class.
 /// </summary>
 /// <param name="graphics">The graphics interface used for the camera buffer data.</param>
 public CameraController(GorgonGraphics graphics)
 {
     Graphics      = graphics;
     _cameraBuffer = GorgonConstantBufferView.CreateConstantBuffer(graphics,
                                                                   ref _viewProjectionMatrix,
                                                                   "Gorgon 2D Camera Constant Buffer",
                                                                   ResourceUsage.Dynamic);
 }
Exemplo n.º 4
0
        /// <summary>
        /// Function to set a constant buffer for a specific shader stage.
        /// </summary>
        /// <param name="constantBuffer">The constant buffer to assign.</param>
        /// <param name="slot">The slot for the constant buffer.</param>
        /// <returns>The fluent builder interface.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="slot"/> is less than 0, or greater than/equal to <see cref="GorgonConstantBuffers.MaximumConstantBufferCount"/>.</exception>
        public Gorgon2DShaderStateBuilder <T> ConstantBuffer(GorgonConstantBufferView constantBuffer, int slot = 0)
        {
            if ((slot < 0) || (slot >= GorgonConstantBuffers.MaximumConstantBufferCount))
            {
                throw new ArgumentOutOfRangeException(nameof(slot), string.Format(Resources.GOR2D_ERR_CBUFFER_SLOT_INVALID, GorgonConstantBuffers.MaximumConstantBufferCount));
            }

            _workingShader.RwConstantBuffers[slot] = constantBuffer;
            return(this);
        }
        /// <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();
        }
Exemplo n.º 6
0
        /// <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()
        {
            var globalData = new GlobalEffectData
            {
                CameraPosition = DX.Vector3.Zero,
                FlipYNormal    = 0
            };

            _globalData = GorgonConstantBufferView.CreateConstantBuffer(Graphics, ref globalData, "Global deferred light effect data.", ResourceUsage.Default);

            _lightData = GorgonConstantBufferView.CreateConstantBuffer(Graphics,
                                                                       new GorgonConstantBufferInfo("Deferred Lighting Light Data Buffer")
            {
                SizeInBytes = Unsafe.SizeOf <PointLightData>(),
                Usage       = ResourceUsage.Dynamic
            });

            Macros.Add(new GorgonShaderMacro("DEFERRED_LIGHTING"));
            _vertexDeferShader      = CompileShader <GorgonVertexShader>(Resources.Lighting, "GorgonVertexLightingShader");
            _vertexDeferShaderState = VertexShaderBuilder.Shader(_vertexDeferShader)
                                      .Build();

            _pixelDeferShader      = CompileShader <GorgonPixelShader>(Resources.Lighting, "GorgonPixelShaderDeferred");
            _pixelDeferShaderState = PixelShaderBuilder.Shader(_pixelDeferShader)
                                     .SamplerState(_diffuseFilter, 0)
                                     .SamplerState(_normalFilter, 1)
                                     .SamplerState(_specularFilter, 2)
                                     .Build();

            Macros.Clear();
            Macros.Add(new GorgonShaderMacro("LIGHTS"));
            _vertexLitShader      = CompileShader <GorgonVertexShader>(Resources.Lighting, "GorgonVertexLitShader");
            _vertexLitShaderState = VertexShaderBuilder.Shader(_vertexLitShader)
                                    .Build();

            _pixelLitShader      = CompileShader <GorgonPixelShader>(Resources.Lighting, "GorgonPixelShaderLighting");
            _pixelLitShaderState = PixelShaderBuilder.Shader(_pixelLitShader)
                                   .ConstantBuffer(_lightData, 1)
                                   .ConstantBuffer(_globalData, 2)
                                   .SamplerState(_diffuseFilter, 0)
                                   .SamplerState(_normalFilter, 1)
                                   .SamplerState(_specularFilter, 2)
                                   .Build();

            // Rebuild our states for the new pixel shaders.
            _lightingState = BatchStateBuilder.PixelShaderState(_pixelLitShaderState)
                             .VertexShaderState(_vertexLitShaderState)
                             .BlendState(GorgonBlendState.Additive)
                             .Build();
        }
Exemplo n.º 7
0
        /// <summary>
        /// Function to create a new constant buffer so we can upload data to the shaders on the GPU.
        /// </summary>
        /// <param name="window">The application window.</param>
        private static void CreateConstantBuffer(Form window)
        {
            // Our projection matrix.

            // Build our projection matrix using a 65 degree field of view and an aspect ratio that matches our current window aspect ratio.
            // Note that we depth a depth range from 0.001f up to 1000.0f.  This provides a near and far plane for clipping.
            // These clipping values must have the world transformed vertex data inside of it or else it will not render. Note that the near/far plane is not a
            // linear range and Z accuracy can get worse the further from the near plane that you get (particularly with depth buffers).
            DX.Matrix.PerspectiveFovLH(65.0f.ToRadians(), window.ClientSize.Width / (float)window.ClientSize.Height, 0.125f, 1000f, out DX.Matrix projectionMatrix);

            // Create our constant buffer.
            //
            // The data we pass into here will apply the projection transformation to our vertex data so we can transform from 3D space into 2D space.
            _constantBuffer = GorgonConstantBufferView.CreateConstantBuffer(_graphics, ref projectionMatrix, "MiniTri WVP Constant Buffer");
        }
Exemplo n.º 8
0
        /// <summary>
        /// Function to build up the constant buffer data for our shaders.
        /// </summary>
        private void BuildConstantBuffers()
        {
            var worldMatrix = DX.Matrix.Identity;

            DX.Vector3 cameraPos     = _viewMatrix.TranslationVector;
            var        emptyMaterial = new Material
            {
                Albedo        = GorgonColor.White,
                SpecularPower = 1.0f,
                UVOffset      = DX.Vector2.Zero
            };

            _viewProjectionBuffer = GorgonConstantBufferView.CreateConstantBuffer(_graphics, ref _viewProjection, "Projection/View Buffer", ResourceUsage.Dynamic);
            _cameraBuffer         = GorgonConstantBufferView.CreateConstantBuffer(_graphics, ref cameraPos, "CameraBuffer", ResourceUsage.Dynamic);
            _worldBuffer          = GorgonConstantBufferView.CreateConstantBuffer(_graphics, ref worldMatrix, "WorldBuffer", ResourceUsage.Dynamic);
            _materialBuffer       = GorgonConstantBufferView.CreateConstantBuffer(_graphics, ref emptyMaterial, "MaterialBuffer", ResourceUsage.Dynamic);

            _lightBuffer = GorgonConstantBufferView.CreateConstantBuffer(_graphics,
                                                                         new GorgonConstantBufferInfo("LightDataBuffer")
            {
                Usage       = ResourceUsage.Default,
                SizeInBytes = Unsafe.SizeOf <LightData>() * MaxLights
            });
        }
Exemplo n.º 9
0
        /// <summary>
        /// Function used to initialize the application.
        /// </summary>
        private static void Initialize()
        {
            GorgonExample.ResourceBaseDirectory = new DirectoryInfo(Settings.Default.ResourceLocation);

            // Build the form so we can actually show something.
            _mainForm = GorgonExample.Initialize(new DX.Size2(1280, 800), "Geometry Shaders");

            try
            {
                // Now we create and enumerate the list of video devices installed in the computer.
                // We must do this in order to tell Gorgon which video device we intend to use. Note that this method may be quite slow (particularly when running DEBUG versions of
                // Direct 3D). To counter this, this object and its Enumerate method are thread safe so this can be run in the background while keeping the main UI responsive.
                //
                // If no suitable device was found (no Direct 3D 11.4 support) in the computer, this method will return an empty list. However, if it succeeds, then the devices list
                // will be populated with an IGorgonVideoDeviceInfo for each suitable video device in the system.
                //
                // Using this method, we could also enumerate the WARP software rasterizer, and/of the D3D Reference device (only if the DEBUG functionality provided by the Windows
                // SDK is installed). These devices are typically used to determine if there's a driver error, and can be terribly slow to render (reference moreso than WARP). It is
                // recommended that these only be used in diagnostic scenarios only.
                IReadOnlyList <IGorgonVideoAdapterInfo> devices = GorgonGraphics.EnumerateAdapters(log: GorgonApplication.Log);

                if (devices.Count == 0)
                {
                    GorgonDialogs.ErrorBox(_mainForm, "This example requires a video adapter that supports Direct3D 11.4 or better.");
                    GorgonApplication.Quit();
                    return;
                }

                // Now we create the main graphics interface with the first applicable video device.
                _graphics = new GorgonGraphics(devices[0], log: GorgonApplication.Log);

                // Check to ensure that we can support the format required for our swap chain.
                // If a video device can't support this format, then the odds are good it won't render anything. Since we're asking for a very common display format, this will
                // succeed nearly 100% of the time. Regardless, it's good form to the check for a working display format prior to setting up the swap chain.
                //
                // This is also used to determine if a format can be used for other objects (e.g. a texture, render target, etc...) And like the swap chain format, it is also best
                // practice to check if the object you're creating supports the desired format.
                if (!_graphics.FormatSupport[BufferFormat.R8G8B8A8_UNorm].IsDisplayFormat)
                {
                    // We should never see this unless you've got some very esoteric hardware.
                    GorgonDialogs.ErrorBox(_mainForm, "We should not see this error.");
                    return;
                }

                // Finally, create a swap chain to display our output.
                // In this case we're setting up our swap chain to bind with our main window, and we use its client size to determine the width/height of the swap chain back buffers.
                // This width/height does not need to be the same size as the window, but, except for some scenarios, that would produce undesirable image quality.
                _swap = new GorgonSwapChain(_graphics,
                                            _mainForm,
                                            new GorgonSwapChainInfo("Main Swap Chain")
                {
                    Format = BufferFormat.R8G8B8A8_UNorm, Width = _mainForm.ClientSize.Width, Height = _mainForm.ClientSize.Height
                });

                // Assign events so we can update our projection with our window size.
                _swap.BeforeSwapChainResized += Swap_BeforeSwapChainResized;
                _swap.AfterSwapChainResized  += Swap_AfterSwapChainResized;

                // We'll need a depth buffer for this example, or else our pyramid will look weird when rotating as back faces will appear through front faces.
                // So, first we should check for support of a proper depth/stencil format.  That said, if we don't have this format, then we're likely not running hardware from the last decade or more.
                if (!_graphics.FormatSupport[BufferFormat.D24_UNorm_S8_UInt].IsDepthBufferFormat)
                {
                    GorgonDialogs.ErrorBox(_mainForm, "A 24 bit depth buffer is required for this example.");
                    return;
                }

                _depthStencil = GorgonDepthStencil2DView.CreateDepthStencil(_graphics,
                                                                            new GorgonTexture2DInfo
                {
                    Format  = BufferFormat.D24_UNorm_S8_UInt,
                    Binding = TextureBinding.DepthStencil,
                    Usage   = ResourceUsage.Default,
                    Width   = _swap.Width,
                    Height  = _swap.Height
                });

                // Load the shaders from a file on disc.
                LoadShaders();

                // Load the texture.
                _texture = GorgonTexture2DView.FromFile(_graphics,
                                                        Path.Combine(GorgonExample.GetResourcePath(@"Textures\GeometryShader\").FullName, "GSTexture.png"),
                                                        new GorgonCodecPng());

                // Create our builders so we can compose a draw call and pipeline state.
                _drawCallBuilder  = new GorgonDrawCallBuilder();
                _pipeStateBuilder = new GorgonPipelineStateBuilder(_graphics);

                // Create a constant buffer so we can adjust the positioning of the data.
                DX.Matrix.PerspectiveFovLH((65.0f).ToRadians(), (float)_swap.Width / _swap.Height, 0.125f, 1000.0f, out _projection);
                _vsConstants = GorgonConstantBufferView.CreateConstantBuffer(_graphics,
                                                                             new GorgonConstantBufferInfo("WorldProjection CBuffer")
                {
                    SizeInBytes = (DX.Matrix.SizeInBytes * 2) + DX.Vector4.SizeInBytes
                });
                _vsConstants.Buffer.SetData(ref _projection, copyMode: CopyMode.Discard);
                _vsConstants.Buffer.SetData(ref _worldMatrix, 64, CopyMode.NoOverwrite);

                // Create a draw call so we actually have something we can draw.
                _drawCall = _drawCallBuilder.VertexRange(0, 3)
                            .PipelineState(_pipeStateBuilder.PixelShader(_pixelShader)
                                           .VertexShader(_bufferless)
                                           .GeometryShader(_geometryShader)
                                           .DepthStencilState(GorgonDepthStencilState.DepthEnabled))
                            .ShaderResource(ShaderType.Pixel, _texture)
                            .ConstantBuffer(ShaderType.Vertex, _vsConstants)
                            .ConstantBuffer(ShaderType.Geometry, _vsConstants)
                            .Build();
                // Finally set our swap chain as the active rendering target and the depth/stencil buffer.
                _graphics.SetRenderTarget(_swap.RenderTargetView, _depthStencil);

                GorgonExample.LoadResources(_graphics);
            }
            finally
            {
                GorgonExample.EndInit();
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Function to initialize the blitter.
        /// </summary>
        public void Initialize()
        {
            try
            {
                // We've been initialized, so leave.
                if ((_vertexShader != null) || (Interlocked.Increment(ref _initializedFlag) > 1))
                {
                    // Trap other threads until we're done initializing and then release them.
                    while ((_vertexShader == null) && (_initializedFlag > 0))
                    {
                        var wait = new SpinWait();
                        wait.SpinOnce();
                    }

                    return;
                }


                _vertexShader = GorgonShaderFactory.Compile <GorgonVertexShader>(_graphics,
                                                                                 Resources.GraphicsShaders,
                                                                                 "GorgonBltVertexShader",
                                                                                 GorgonGraphics.IsDebugEnabled);
                _pixelShader = GorgonShaderFactory.Compile <GorgonPixelShader>(_graphics,
                                                                               Resources.GraphicsShaders,
                                                                               "GorgonBltPixelShader",
                                                                               GorgonGraphics.IsDebugEnabled);

                _inputLayout = GorgonInputLayout.CreateUsingType <BltVertex>(_graphics, _vertexShader);

                _vertexBufferBindings = new GorgonVertexBufferBindings(_inputLayout)
                {
                    [0] = GorgonVertexBufferBinding.CreateVertexBuffer <BltVertex>(_graphics,
                                                                                   4,
                                                                                   ResourceUsage.Dynamic,
                                                                                   bufferName: "Gorgon Blitter Vertex Buffer")
                };

                _wvpBuffer = GorgonConstantBufferView.CreateConstantBuffer(_graphics,
                                                                           new GorgonConstantBufferInfo("Gorgon Blitter WVP Buffer")
                {
                    Usage       = ResourceUsage.Dynamic,
                    SizeInBytes = DX.Matrix.SizeInBytes
                });

                // Finish initalizing the draw call.
                _pipelineState = _pipeStateBuilder.VertexShader(_vertexShader)
                                 .BlendState(GorgonBlendState.NoBlending)
                                 .DepthStencilState(GorgonDepthStencilState.Default)
                                 .PrimitiveType(PrimitiveType.TriangleStrip)
                                 .RasterState(GorgonRasterState.Default)
                                 .PixelShader(_pixelShader)
                                 .Build();

                _drawCallBuilder.VertexBuffers(_inputLayout, _vertexBufferBindings)
                .VertexRange(0, 4)
                .SamplerState(ShaderType.Pixel, GorgonSamplerState.Default)
                .PipelineState(_pipelineState)
                .ConstantBuffer(ShaderType.Vertex, _wvpBuffer);


                _defaultTexture = Resources.White_2x2.ToTexture2D(_graphics,
                                                                  new GorgonTexture2DLoadOptions
                {
                    Name    = "Gorgon_Default_White_Texture",
                    Usage   = ResourceUsage.Immutable,
                    Binding = TextureBinding.ShaderResource
                }).GetShaderResourceView();
            }
            finally
            {
                Interlocked.Decrement(ref _initializedFlag);
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Function to initialize the GPU resource objects.
        /// </summary>
        private static void InitializeGpuResources()
        {
            _graphics = CreateGraphicsInterface();

            // If we couldn't create the graphics interface, then leave.
            if (_graphics == null)
            {
                return;
            }

            // Create a 1280x800 window with a depth buffer.
            // We can modify the resolution in the config file for the application, but like other Gorgon examples, the default is 1280x800.
            _swap = new GorgonSwapChain(_graphics,
                                        _mainForm,
                                        new GorgonSwapChainInfo("Main")
            {
                // Set up for 32 bit RGBA normalized display.
                Format = BufferFormat.R8G8B8A8_UNorm,
                Width  = Settings.Default.Resolution.Width,
                Height = Settings.Default.Resolution.Height
            });

            // Build the depth buffer for our swap chain.
            BuildDepthBuffer(_swap.Width, _swap.Height);


            if (!Settings.Default.IsWindowed)
            {
                // Get the output for the main window.
                var currentScreen             = Screen.FromControl(_mainForm);
                IGorgonVideoOutputInfo output = _graphics.VideoAdapter.Outputs[currentScreen.DeviceName];

                // If we've asked for full screen mode, then locate the correct video mode and set us up.
                _selectedVideoMode = new GorgonVideoMode(Settings.Default.Resolution.Width, Settings.Default.Resolution.Height, BufferFormat.R8G8B8A8_UNorm);
                _swap.EnterFullScreen(in _selectedVideoMode, output);
            }

            // Handle resizing because the projection matrix and depth buffer needs to be updated to reflect the new view size.
            _swap.BeforeSwapChainResized += Swap_BeforeResized;
            _swap.AfterSwapChainResized  += Swap_AfterResized;

            // Set the current render target output so we can see something.
            _graphics.SetRenderTarget(_swap.RenderTargetView, _depthBuffer);

            // Create our shaders.
            // Our vertex shader.  This is a simple shader, it just processes a vertex by multiplying it against
            // the world/view/projection matrix and spits it back out.
            _vertexShader = GorgonShaderFactory.Compile <GorgonVertexShader>(_graphics, Resources.Shader, "BoingerVS");

            // Our main pixel shader.  This is a very simple shader, it just reads a texture and spits it back out.  Has no
            // diffuse capability.
            _pixelShader = GorgonShaderFactory.Compile <GorgonPixelShader>(_graphics, Resources.Shader, "BoingerPS");

            // Create the vertex input layout.
            // We need to create a layout for our vertex type because the shader won't know how to interpret the data we're sending it otherwise.
            // This is why we need a vertex shader before we even create the layout.
            _inputLayout = GorgonInputLayout.CreateUsingType <BoingerVertex>(_graphics, _vertexShader);

            // Resources are stored as System.Drawing.Bitmap files, so we need to convert into an IGorgonImage so we can upload it to a texture.
            // We also will generate mip-map levels for this image so that scaling the texture will look better.
            using (IGorgonImage image = Resources.Texture.ToGorgonImage())
            {
                _texture = image.ToTexture2D(_graphics,
                                             new GorgonTexture2DLoadOptions
                {
                    Usage = ResourceUsage.Immutable,
                    Name  = "Texture"
                })
                           .GetShaderResourceView();
            }

            // Create our constant buffer.
            // Our constant buffers are how we send data to our shaders.  This one in particular will be responsible for sending our world/view/projection matrix
            // to the vertex shader.
            _wvpBuffer = GorgonConstantBufferView.CreateConstantBuffer(_graphics,
                                                                       new GorgonConstantBufferInfo("WVPBuffer")
            {
                Usage       = ResourceUsage.Dynamic,
                SizeInBytes = DX.Matrix.SizeInBytes
            });
            // This one will hold our material information.
            _materialBuffer = GorgonConstantBufferView.CreateConstantBuffer(_graphics,
                                                                            new GorgonConstantBufferInfo("MaterialBuffer")
            {
                Usage       = ResourceUsage.Dynamic,
                SizeInBytes = Unsafe.SizeOf <GorgonColor>()
            });
            GorgonColor defaultMaterialColor = GorgonColor.White;

            _materialBuffer.Buffer.SetData(ref defaultMaterialColor);

            GorgonExample.LoadResources(_graphics);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            GorgonConstantBufferView buffer = Interlocked.Exchange(ref _cameraBuffer, null);

            buffer?.Dispose();
        }