Ejemplo n.º 1
0
 /// <summary>
 /// Function to build or rebuild the depth buffer.
 /// </summary>
 /// <param name="width">The width of the depth buffer.</param>
 /// <param name="height">The height of the depth buffer.</param>
 private static void BuildDepthBuffer(int width, int height)
 {
     _depthBuffer?.Dispose();
     _depthBuffer = GorgonDepthStencil2DView.CreateDepthStencil(_graphics,
                                                                new GorgonTexture2DInfo
     {
         Usage   = ResourceUsage.Default,
         Width   = width,
         Height  = height,
         Format  = BufferFormat.D24_UNorm_S8_UInt,
         Binding = TextureBinding.DepthStencil
     });
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Function to build or rebuild the depth buffer.
 /// </summary>
 /// <param name="width">The width of the depth buffer.</param>
 /// <param name="height">The height of the depth buffer.</param>
 private static void BuildDepthBuffer(int width, int height)
 {
     _graphics.SetDepthStencil(null);
     _depthBuffer?.Dispose();
     _depthBuffer = GorgonDepthStencil2DView.CreateDepthStencil(_graphics,
                                                                new GorgonTexture2DInfo("Depth Buffer")
     {
         Usage  = ResourceUsage.Default,
         Width  = width,
         Height = height,
         Format = _depthFormat
     });
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Handles the AfterSwapChainResized event of the Swap control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="AfterSwapChainResizedEventArgs"/> instance containing the event data.</param>
        private static void Swap_AfterSwapChainResized(object sender, AfterSwapChainResizedEventArgs e)
        {
            // We need to recreate the depth/stencil here to match the updated size of the render target (the depth/stencil and render targets must be the same size).
            _depthStencil = GorgonDepthStencil2DView.CreateDepthStencil(_graphics,
                                                                        new GorgonTexture2DInfo
            {
                Format  = BufferFormat.D24_UNorm_S8_UInt,
                Binding = TextureBinding.DepthStencil,
                Usage   = ResourceUsage.Default,
                Width   = _swap.Width,
                Height  = _swap.Height
            });
            _graphics.SetDepthStencil(_depthStencil);

            // When we resize, the projection matrix will go out of date, so we need to update our constant buffer with an updated projection.
            DX.Matrix.PerspectiveFovLH((65.0f).ToRadians(), (float)_swap.Width / _swap.Height, 0.125f, 1000.0f, out _projection);
            _vsConstants.Buffer.SetData(ref _projection);
        }
Ejemplo n.º 4
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();
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Function to initialize the application.
        /// </summary>
        /// <returns>The main window for the application.</returns>
        private static FormMain Initialize()
        {
            GorgonExample.ResourceBaseDirectory   = new DirectoryInfo(Settings.Default.ResourceLocation);
            GorgonExample.PlugInLocationDirectory = new DirectoryInfo(Settings.Default.PlugInLocation);

            FormMain window = GorgonExample.Initialize(new DX.Size2(Settings.Default.Resolution.Width, Settings.Default.Resolution.Height), "Depth");

            try
            {
                IReadOnlyList <IGorgonVideoAdapterInfo> videoDevices = GorgonGraphics.EnumerateAdapters(log: GorgonApplication.Log);

                if (videoDevices.Count == 0)
                {
                    throw new GorgonException(GorgonResult.CannotCreate,
                                              "Gorgon requires at least a Direct3D 11.4 capable video device.\nThere is no suitable device installed on the system.");
                }

                // Find the best video device.
                _graphics = new GorgonGraphics(videoDevices.OrderByDescending(item => item.FeatureSet).First());

                _screen = new GorgonSwapChain(_graphics,
                                              window,
                                              new GorgonSwapChainInfo("Gorgon2D Depth Buffer Example")
                {
                    Width  = Settings.Default.Resolution.Width,
                    Height = Settings.Default.Resolution.Height,
                    Format = BufferFormat.R8G8B8A8_UNorm
                });

                _depthBuffer = GorgonDepthStencil2DView.CreateDepthStencil(_graphics, new GorgonTexture2DInfo(_screen.RenderTargetView)
                {
                    Binding = TextureBinding.DepthStencil,
                    Format  = BufferFormat.D24_UNorm_S8_UInt
                });

                // Tell the graphics API that we want to render to the "screen" swap chain.
                _graphics.SetRenderTarget(_screen.RenderTargetView, _depthBuffer);

                // Initialize the renderer so that we are able to draw stuff.
                _renderer = new Gorgon2D(_graphics);

                GorgonExample.LoadResources(_graphics);

                // Load our packed file system plug in.
                _assemblyCache = new GorgonMefPlugInCache(GorgonApplication.Log);
                _assemblyCache.LoadPlugInAssemblies(GorgonExample.GetPlugInPath().FullName, "Gorgon.FileSystem.GorPack.dll");
                IGorgonPlugInService plugIns = new GorgonMefPlugInService(_assemblyCache);

                // Load the file system containing our application data (sprites, images, etc...)
                IGorgonFileSystemProviderFactory providerFactory = new GorgonFileSystemProviderFactory(plugIns, GorgonApplication.Log);
                IGorgonFileSystemProvider        provider        = providerFactory.CreateProvider("Gorgon.IO.GorPack.GorPackProvider");
                IGorgonFileSystem fileSystem = new GorgonFileSystem(provider, GorgonApplication.Log);

                // We can load the editor file system directly.
                // This is handy for switching a production environment where your data may be stored
                // as a compressed file, and a development environment where your data consists of loose
                // files.
                // fileSystem.Mount(@"D:\unpak\scratch\DeepAsAPuddle.gorPack\fs\");

                // For now though, we'll load the packed file.
                fileSystem.Mount(Path.Combine(GorgonExample.GetResourcePath(@"FileSystems").FullName, "Depth.gorPack"));

                // Get our sprites.  These make up the frames of animation for our Guy.
                // If and when there's an animation editor, we'll only need to create a single sprite and load the animation.
                IGorgonVirtualFile[] spriteFiles = fileSystem.FindFiles("/Sprites/", "*", true).ToArray();

                // Load our sprite data (any associated textures will be loaded as well).
                Dictionary <string, GorgonSprite> sprites = new Dictionary <string, GorgonSprite>(StringComparer.OrdinalIgnoreCase);

                for (int i = 0; i < spriteFiles.Length; i++)
                {
                    IGorgonVirtualFile file = spriteFiles[i];
                    (GorgonSprite sprite, GorgonTexture2D texture) = fileSystem.LoadSprite(_renderer, file.FullPath);

                    // The LoadSprite extension method will automatically find and load your associated texture if you're using
                    // a Gorgon editor file system. So it's important that you leep track of your textures, disposing of just
                    // the associated GorgonTexture2DView won't cut it here, so you'll need to dispose the actual texture resource
                    // when you're done with it.
                    if (!_textures.Contains(texture))
                    {
                        _textures.Add(texture);
                    }

                    // At super duper resolution, the example graphics would be really hard to see, so we'll scale them up.
                    sprite.Scale       = new DX.Vector2((_screen.Width / (_screen.Height / 2)) * 2.0f);
                    sprites[file.Name] = sprite;
                }

                _snowTile       = sprites["Snow"];
                _snowTile.Depth = 0.5f;

                _icicle       = sprites["Icicle"];
                _icicle.Depth = 0.2f;

                _guySprite       = sprites["Guy_Up_0"];
                _guySprite.Depth = 0.1f;
                _guyPosition     = new DX.Vector2(_screen.Width / 2 + _guySprite.ScaledSize.Width * 1.25f, _screen.Height / 2 + _guySprite.ScaledSize.Height);

                BuildAnimations(sprites);
            }
            finally
            {
                GorgonExample.EndInit();
            }

            return(window);
        }