/// <summary> /// Handles the KeyUp event of the MainForm control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param> private static void MainForm_KeyUp(object sender, KeyEventArgs e) { if ((e.KeyCode != Keys.Enter) || (!e.Alt) || (_swap == null)) { return; } if (!_swap.IsWindowed) { _swap.ExitFullScreen(); return; } IGorgonVideoOutputInfo output = _graphics.VideoAdapter.Outputs[GorgonApplication.MainForm.Handle]; if (output == null) { return; } // Find an appropriate video mode. var searchMode = new GorgonVideoMode(GorgonApplication.MainForm.ClientSize.Width, GorgonApplication.MainForm.ClientSize.Height, BufferFormat.R8G8B8A8_UNorm); output.VideoModes.FindNearestVideoMode(output, in searchMode, out GorgonVideoMode nearestMode); // To enter full screen borderless window mode, call EnterFullScreen with no parameters. _swap.EnterFullScreen(in nearestMode, output); }
/// <summary> /// Function to create the primary graphics interface. /// </summary> /// <returns>A new graphics interface, or <b>null</b> if a suitable video device was not found on the system.</returns> /// <remarks> /// <para> /// This method will create a new graphics interface for our application to use. It will select the video device with the most suitable depth buffer available, and if it cannot find a suitable /// device, it will indicate that by returning <b>null</b>. /// </para> /// </remarks> private static GorgonGraphics CreateGraphicsInterface() { GorgonGraphics graphics = null; BufferFormat[] depthFormats = { BufferFormat.D32_Float, BufferFormat.D32_Float_S8X24_UInt, BufferFormat.D24_UNorm_S8_UInt, BufferFormat.D16_UNorm }; // Find out which devices we have installed in the system. IReadOnlyList <IGorgonVideoAdapterInfo> deviceList = GorgonGraphics.EnumerateAdapters(); if (deviceList.Count == 0) { GorgonDialogs.ErrorBox(_mainForm, "There are no suitable video adapters available in the system. This example is unable to continue and will now exit."); return(null); } int depthFormatIndex = 0; int selectedDeviceIndex = 0; IGorgonVideoAdapterInfo selectedDevice = null; _selectedVideoMode = new GorgonVideoMode(Settings.Default.Resolution.Width, Settings.Default.Resolution.Height, BufferFormat.R8G8B8A8_UNorm); while (selectedDeviceIndex < deviceList.Count) { // Reset back to a 32 bit floating point depth. _depthFormat = depthFormats[depthFormatIndex++]; // Destroy the previous interface. graphics?.Dispose(); // Create the main graphics interface. graphics = new GorgonGraphics(deviceList[selectedDeviceIndex++]); // Validate depth buffer for this device. // Odds are good that if this fails, you should probably invest in a better video card. Preferably something created after 2005. if (!graphics.FormatSupport[_depthFormat].IsDepthBufferFormat) { continue; } selectedDevice = graphics.VideoAdapter; break; } // If, somehow, we are on a device from the dark ages, then we can't continue. if (selectedDevice != null) { return(graphics); } GorgonDialogs.ErrorBox(_mainForm, $"The selected video device ('{deviceList[0].Name}') does not support a 32, 24 or 16 bit depth buffer."); return(null); }
/// <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); }
/// <summary> /// Handles the KeyDown event of the _form control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="KeyEventArgs"/> instance containing the event data.</param> private static void Form_KeyDown(object sender, KeyEventArgs e) { int ballIncrement = 1; switch (e.KeyCode) { case Keys.Pause: _paused = !_paused; break; case Keys.F1: _showHelp = !_showHelp; break; case Keys.Up: if ((e.Control) && (e.Shift)) { ballIncrement = 1000; } else { if (e.Control) { ballIncrement = 100; } if (e.Shift) { ballIncrement = 10; } } GenerateBalls(ballIncrement); break; case Keys.Down: if ((e.Control) && (e.Shift)) { ballIncrement = 1000; } else { if (e.Control) { ballIncrement = 100; } if (e.Shift) { ballIncrement = 10; } } GenerateBalls(-ballIncrement); break; case Keys.Enter: if (e.Alt) { if (_mainScreen.IsWindowed) { IGorgonVideoOutputInfo output = _graphics.VideoAdapter.Outputs[_window.Handle]; if (output == null) { _mainScreen.EnterFullScreen(); } else { var mode = new GorgonVideoMode(_window.ClientSize.Width, _window.ClientSize.Height, BufferFormat.R8G8B8A8_UNorm); _mainScreen.EnterFullScreen(in mode, output); } } else { _mainScreen.ExitFullScreen(); } } break; case Keys.OemMinus: _blur.BlurRadius--; if (_blur.BlurRadius < 0) { _blur.BlurRadius = 0; } break; case Keys.Oemplus: _blur.BlurRadius++; if (_blur.BlurRadius > _blur.MaximumBlurRadius) { _blur.BlurRadius = _blur.MaximumBlurRadius; } break; } }