private static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); try { // Now begin running the application idle loop. GorgonApplication.Run(Initialize(), Idle); } catch (Exception ex) { GorgonExample.HandleException(ex); } finally { // Always clean up when you're done. // Since Gorgon uses Direct 3D 11.1, which allocate objects that use native memory and COM objects, we must be careful to dispose of any objects that implement // IDisposable. Failure to do so can lead to warnings from the Direct 3D runtime when running in DEBUG mode. GorgonExample.UnloadResources(); _texture?.Dispose(); _constantBuffer?.Dispose(); _vertexBuffer.VertexBuffer?.Dispose(); _inputLayout?.Dispose(); _vertexShader?.Dispose(); _pixelShader?.Dispose(); _swap?.Dispose(); _graphics?.Dispose(); } }
/// <summary>Raises the <see cref="E:System.Windows.Forms.Form.Load" /> event.</summary> /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data. </param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); _gifAnim = new GifAnimator(SynchronizationContext.Current); _gallery = new ImageGallery(Font, DeviceDpi, _gifAnim); try { Cursor.Current = Cursors.WaitCursor; // Load our image data. _gallery.LoadImages(GorgonApplication.StartupPath.FullName); // Begin our animation. _gifAnim.Animate(() => { using (System.Drawing.Graphics graphics = CreateGraphics()) { _gallery.RefreshGif(graphics); } }); } catch (Exception ex) { GorgonExample.HandleException(ex); GorgonApplication.Quit(); } finally { Cursor.Current = Cursors.Default; } }
/// <summary> /// Function to handle idle time for the application. /// </summary> /// <returns><b>true</b> to continue processing, <b>false</b> to stop.</returns> private static bool Idle() { // Rotate our pyramid. _angle += 45.0f * GorgonTiming.Delta; if (_angle > 360.0f) { _angle -= 360.0f; } // This will allow us to animate the center point of our pyramid. _heightOffset = _angle.ToRadians().FastSin().Abs(); // Send the animated variables to their respective shaders. UpdatedWorldProjection(); // Clear our render target. _swap.RenderTargetView.Clear(Color.CornflowerBlue); _depthStencil.ClearDepth(1.0f); _graphics.Submit(_drawCall); GorgonExample.BlitLogo(_graphics); // Send the contents of the swap chain buffers to the screen. _swap.Present(1); return(true); }
/// <summary> /// Function to load in the gaming device driver plug ins. /// </summary> /// <returns>A list of gaming device driver plug ins.</returns> private static IReadOnlyList <IGorgonGamingDeviceDriver> GetGamingDeviceDrivers() { GorgonExample.PlugInLocationDirectory = new DirectoryInfo(Settings.Default.InputPlugInPath); // Access our plugin cache. _pluginCache = new GorgonMefPlugInCache(GorgonApplication.Log); // Get the files from the plugin directory. // The plugin directory can be changed in the configuration file // to point at wherever you'd like. If a {0} place holder is // in the path, it will be replaced with whatever the build // configuration is set to (i.e. DEBUG or RELEASE). _pluginCache.LoadPlugInAssemblies(GorgonExample.GetPlugInPath().FullName, "Gorgon.Input.*.dll"); if (_pluginCache.PlugInAssemblies.Count == 0) { return(Array.Empty <IGorgonGamingDeviceDriver>()); } // Create our plugin service. IGorgonPlugInService pluginService = new GorgonMefPlugInService(_pluginCache); // Create our input service factory. var factory = new GorgonGamingDeviceDriverFactory(pluginService, GorgonApplication.Log); // Retrieve the list of driver plug ins from the input service factory. return(factory.LoadAllDrivers()); }
/// <summary> /// Function called during idle time. /// </summary> /// <returns><b>true</b> to continue execution, <b>false</b> to stop.</returns> private bool Idle() { _swap.RenderTargetView.Clear(GorgonColor.White); var windowSize = new DX.Size2F(ClientSize.Width, ClientSize.Height); var imageSize = new DX.Size2F(_texture.Width, _texture.Height); // Calculate the scale between the images. var scale = new DX.Size2F(windowSize.Width / imageSize.Width, windowSize.Height / imageSize.Height); // Only scale on a single axis if we don't have a 1:1 aspect ratio. if (scale.Height > scale.Width) { scale.Height = scale.Width; } else { scale.Width = scale.Height; } // Scale the image. var size = new DX.Size2((int)(scale.Width * imageSize.Width), (int)(scale.Height * imageSize.Height)); // Find the position. var bounds = new DX.Rectangle((int)((windowSize.Width / 2) - (size.Width / 2)), (int)((windowSize.Height / 2) - (size.Height / 2)), size.Width, size.Height); _graphics.DrawTexture(_texture, bounds); GorgonExample.BlitLogo(_graphics); _swap.Present(1); return(true); }
private static void Main() { try { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Initialize(); GorgonApplication.Run(_mainForm, Idle); } catch (Exception ex) { GorgonExample.HandleException(ex); } finally { GorgonExample.UnloadResources(); // Always clean up when you're done. // Since Gorgon uses Direct 3D 11.4, we must be careful to dispose of any objects that implement IDisposable. // Failure to do so can lead to warnings from the Direct 3D runtime when running in DEBUG mode. _depthStencil?.Dispose(); _texture?.Dispose(); _geometryShader?.Dispose(); _pixelShader?.Dispose(); _vertexShader?.Dispose(); _bufferless?.Dispose(); _swap?.Dispose(); _graphics?.Dispose(); } }
/// <summary> /// Function to handle idle time for the application. /// </summary> /// <returns><b>true</b> to continue processing, <b>false</b> to stop.</returns> private static bool Idle() { // Animate the ball. UpdateBall(); // Clear to our gray color and clear out the depth buffer. _swap.RenderTargetView.Clear(Color.FromArgb(173, 173, 173)); //_depthBuffer.Clear(0.0f, 0); _depthBuffer.Clear(0.0f, 0); // Render the back and floor planes. // ReSharper disable once ForCanBeConvertedToForeach for (int i = 0; i < _planes.Length; ++i) { RenderModel(_planes[i]); } // Render the ball. _sphere.Material.Diffuse = GorgonColor.White; RenderModel(_sphere); // Remember the position and rotation so we can restore them later. DX.Vector3 spherePosition = _sphere.Position; DX.Vector3 sphereRotation = _sphere.Rotation; // Offset the position of the ball so we can fake a shadow under the ball. _sphere.Position = new DX.Vector3(spherePosition.X + 0.25f, spherePosition.Y - 0.125f, spherePosition.Z + 0.5f); // Scale on the z-axis so the ball "shadow" has no real depth, and on the x & y to make it look slightly bigger. _sphere.Scale = new DX.Vector3(1.155f, 1.155f, 0.001f); // Reset the rotation so we don't rotate our flattened ball "shadow" (it'd look real weird if it rotated). _sphere.Rotation = DX.Vector3.Zero; // Render as black with alpha of 0.5 to simulate a shadow. _sphere.Material.Diffuse = new GorgonColor(0, 0, 0, 0.5f); // Render the shadow. RenderModel(_sphere); // Restore our original positioning so we can render the ball in the correct place on the next frame. _sphere.Position = spherePosition; // Reset scale on the z-axis so the ball so it'll be normal for the next frame. _sphere.Scale = DX.Vector3.One; // Reset the rotation so it'll be in the correct place on the next frame. _sphere.Rotation = sphereRotation; // Draw our text. // Use this to show how incredibly slow and terrible my 3D code is. GorgonExample.DrawStatsAndLogo(_2D); // Now we flip our buffers. // We need to this or we won't see anything. _swap.Present(1); return(true); }
/// <summary> /// Raises the <see cref="E:System.Windows.Forms.Form.FormClosing" /> event. /// </summary> /// <param name="e">A <see cref="T:System.Windows.Forms.FormClosingEventArgs" /> that contains the event data.</param> protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); GorgonExample.UnloadResources(); _pluginCache?.Dispose(); _texture?.Dispose(); _swap?.Dispose(); _graphics?.Dispose(); _image?.Dispose(); }
static void Main() { try { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); GorgonApplication.Run(new MainForm()); } catch (Exception ex) { GorgonExample.HandleException(ex); } }
/// <summary> /// Function to handle idle time for the application. /// </summary> /// <returns><b>true</b> to continue processing, <b>false</b> to stop.</returns> private static bool Idle() { // This will clear the swap chain to the specified color. _swap.RenderTargetView.Clear(Color.CornflowerBlue); // Draw our triangle. _graphics.Submit(_drawCall); GorgonExample.BlitLogo(_graphics); // Now we flip our buffers on the swap chain. // We need to this or we won't see anything at all except the standard window background color. Clearly, we don't want that. // This method will take the current frame back buffer and flip it to the front buffer (the window). If we had more than one swap chain tied to multiple // windows, then we'd need to do this for every swap chain. _swap.Present(1); return(true); }
private static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); try { Initialize(); GorgonApplication.Run(_mainForm, Idle); } catch (Exception ex) { GorgonExample.HandleException(ex); } finally { GorgonExample.UnloadResources(); _2D.Dispose(); // Always call dispose so we can free the native memory allocated for the backing graphics API. _sphere?.Dispose(); if (_planes != null) { foreach (Plane plane in _planes) { plane?.Dispose(); } } _texture?.Dispose(); _wvpBuffer?.Dispose(); _materialBuffer?.Dispose(); _vertexShader?.Dispose(); _pixelShader?.Dispose(); _inputLayout?.Dispose(); _swap?.Dispose(); _graphics?.Dispose(); } }
/// <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> /// 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(); } }
/// <summary> /// Function to initialize the application. /// </summary> /// <returns>The application window.</returns> private static FormMain Initialize() { GorgonExample.ResourceBaseDirectory = new DirectoryInfo(Settings.Default.ResourceLocation); // Create our form and center on the primary monitor. FormMain window = GorgonExample.Initialize(new DX.Size2(1280, 800), "Gorgon MiniTri - Now with 100% more textures."); try { // First 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. // Find out which devices we have installed in the system. // If no suitable device was found (no Direct 3D 12.0 support) in the computer, this method will throw an exception. However, if it succeeds, then the devices object // will be populated with the IGorgonVideoDeviceInfo for each video device in the system. // // Using this method, we could also enumerate the software rasterizer. These devices are typically used to determine if there's a driver error, and can be terribly slow to render // It is recommended that these only be used in diagnostic scenarios only. IReadOnlyList <IGorgonVideoAdapterInfo> deviceList = GorgonGraphics.EnumerateAdapters(); if (deviceList.Count == 0) { throw new NotSupportedException("There are no suitable video adapters available in the system. This example is unable to continue and will now exit."); } // Now we create the main graphics interface with the first applicable video device. _graphics = new GorgonGraphics(deviceList[0]); // 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 (unless you've somehow gotten an ancient video device to work with Direct 3D 11.1). Regardless, it's good form to the check for a // working display format prior to setting up the swap chain. // // This method is also used to determine if a format can be used for other objects (e.g. a texture, render target, etc...) Like the swap chain format, this is also a // best practice to check if the object you're creating supports the desired format. if ((_graphics.FormatSupport[BufferFormat.R8G8B8A8_UNorm].FormatSupport & BufferFormatSupport.Display) != BufferFormatSupport.Display) { // We should never see this unless you've performed some form of black magic. GorgonDialogs.ErrorBox(window, "We should not see this error."); return(window); } // 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, window, new GorgonSwapChainInfo("Main Swap Chain") { Format = BufferFormat.R8G8B8A8_UNorm, Width = window.ClientSize.Width, Height = window.ClientSize.Height }) { DoNotAutoResizeBackBuffer = true }; // Create the shaders used to render the triangle. // These shaders provide transformation and coloring for the output pixel data. CreateShaders(); // Set up our input layout. // // We'll be using this to describe to Direct 3D how the elements of a vertex is laid out in memory. // In order to provide synchronization between the layout on the CPU side and the GPU side, we have to pass the vertex shader because it will contain the vertex // layout to match with our C# input layout. _inputLayout = GorgonInputLayout.CreateUsingType <MiniTriVertex>(_graphics, _vertexShader); // Load our texture so that we can apply it to our triangle. // // We load this first so we can use some functionality present on the texture to calculate the texture space coordinates required to render with the texture. _texture = GorgonTexture2DView.FromFile(_graphics, Path.Combine(GorgonExample.GetResourcePath(@"Textures\MiniTri\").FullName, "Gorgon.MiniTri.png"), new GorgonCodecPng()); // Set up the triangle vertices. CreateVertexBuffer(); // Set up the constant buffer. // // This is used (but could be used for more) to transform the vertex data from 3D space into 2D space. CreateConstantBuffer(window); // This defines where to send the pixel data when rendering. For now, this goes to our swap chain. _graphics.SetRenderTarget(_swap.RenderTargetView); // Create our draw call. // // This will pass all the necessary information to the GPU to render the triangle // // Since draw calls are immutable objects, we use builders to create them (and any pipeline state). Once a draw // call is built, it cannot be changed (except for the vertex, and if applicable, index, and instance ranges). // // Builders work on a fluent interface. Much like LINQ and can be used to create multiple draw calls from the same // builder. var drawCallBuilder = new GorgonDrawCallBuilder(); var pipelineStateBuilder = new GorgonPipelineStateBuilder(_graphics); _drawCall = drawCallBuilder.VertexBuffer(_inputLayout, _vertexBuffer) .VertexRange(0, 3) .ConstantBuffer(ShaderType.Vertex, _constantBuffer) .ShaderResource(ShaderType.Pixel, _texture) .PipelineState(pipelineStateBuilder .PixelShader(_pixelShader) .VertexShader(_vertexShader) .RasterState(GorgonRasterState.NoCulling)) .Build(); GorgonExample.LoadResources(_graphics); return(window); } finally { GorgonExample.EndInit(); } }
/// <summary> /// Raises the <see cref="E:System.Windows.Forms.Form.Load"></see> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); try { GorgonExample.PlugInLocationDirectory = new DirectoryInfo(Settings.Default.PlugInLocation); // Load the assembly. _assemblyCache = new GorgonMefPlugInCache(GorgonApplication.Log); // Create the plugin service. IGorgonPlugInService plugInService = new GorgonMefPlugInService(_assemblyCache); // Create the factory to retrieve gaming device drivers. var factory = new GorgonGamingDeviceDriverFactory(plugInService); // Create the raw input interface. _input = new GorgonRawInput(this, GorgonApplication.Log); // Get available gaming device driver plug ins. _assemblyCache.LoadPlugInAssemblies(GorgonExample.GetPlugInPath().FullName, "Gorgon.Input.DirectInput.dll"); _assemblyCache.LoadPlugInAssemblies(GorgonExample.GetPlugInPath().FullName, "Gorgon.Input.XInput.dll"); _drivers = factory.LoadAllDrivers(); _joystickList = new List <IGorgonGamingDevice>(); // Get all gaming devices from the drivers. foreach (IGorgonGamingDeviceDriver driver in _drivers) { IReadOnlyList <IGorgonGamingDeviceInfo> infoList = driver.EnumerateGamingDevices(true); foreach (IGorgonGamingDeviceInfo info in infoList) { IGorgonGamingDevice device = driver.CreateGamingDevice(info); // Turn off dead zones for this example. foreach (GorgonGamingDeviceAxis axis in device.Axis) { axis.DeadZone = GorgonRange.Empty; } _joystickList.Add(device); } } // Create mouse. _mouse = new GorgonRawMouse(); // Create the graphics interface. ClientSize = Settings.Default.Resolution; IReadOnlyList <IGorgonVideoAdapterInfo> adapters = GorgonGraphics.EnumerateAdapters(); _graphics = new GorgonGraphics(adapters[0], log: GorgonApplication.Log); _screen = new GorgonSwapChain(_graphics, this, new GorgonSwapChainInfo("INeedYourInput Swapchain") { Width = Settings.Default.Resolution.Width, Height = Settings.Default.Resolution.Height, Format = BufferFormat.R8G8B8A8_UNorm }); _graphics.SetRenderTarget(_screen.RenderTargetView); if (!Settings.Default.IsWindowed) { _screen.EnterFullScreen(); } // For the backup image. Used to make it as large as the monitor that we're on. var currentScreen = Screen.FromHandle(Handle); // Relocate the window to the center of the screen. Location = new Point(currentScreen.Bounds.Left + (currentScreen.WorkingArea.Width / 2) - (ClientSize.Width / 2), currentScreen.Bounds.Top + (currentScreen.WorkingArea.Height / 2) - (ClientSize.Height / 2)); // Create the 2D renderer. _2D = new Gorgon2D(_graphics); // Create the text font. var fontFactory = new GorgonFontFactory(_graphics); _font = fontFactory.GetFont(new GorgonFontInfo("Arial", 9.0f, FontHeightMode.Points, "Arial 9pt") { FontStyle = FontStyle.Bold, AntiAliasingMode = FontAntiAliasMode.AntiAlias }); // Create text sprite. _messageSprite = new GorgonTextSprite(_font, "Using mouse and keyboard (Windows Forms).") { Color = Color.Black }; // Create a back buffer. _backBuffer = GorgonRenderTarget2DView.CreateRenderTarget(_graphics, new GorgonTexture2DInfo("Backbuffer storage") { Width = _screen.Width, Height = _screen.Height, Format = _screen.Format }); _backBuffer.Clear(Color.White); _backBufferView = _backBuffer.GetShaderResourceView(); // Clear our backup image to white to match our primary screen. using (IGorgonImage image = new GorgonImage(new GorgonImageInfo(ImageType.Image2D, _screen.Format) { Width = _screen.Width, Height = _screen.Height, Format = _screen.Format })) { image.Buffers[0].Fill(0xff); _backupImage = image.ToTexture2D(_graphics, new GorgonTexture2DLoadOptions { Binding = TextureBinding.None, Usage = ResourceUsage.Staging }); } // Set gorgon events. _screen.BeforeSwapChainResized += BeforeSwapChainResized; _screen.AfterSwapChainResized += AfterSwapChainResized; // Enable the mouse. Cursor = Cursors.Cross; _mouse.MouseButtonDown += MouseInput; _mouse.MouseMove += MouseInput; _mouse.MouseWheelMove += (sender, args) => { _radius += args.WheelDelta.Sign(); if (_radius < 2.0f) { _radius = 2.0f; } if (_radius > 10.0f) { _radius = 10.0f; } }; // Set the mouse position. _mouse.Position = new Point(ClientSize.Width / 2, ClientSize.Height / 2); _noBlending = _blendBuilder.BlendState(GorgonBlendState.NoBlending) .Build(); _inverted = _blendBuilder.BlendState(GorgonBlendState.Inverted) .Build(); // Set up blending states for our pen. var blendStateBuilder = new GorgonBlendStateBuilder(); _currentBlend = _drawModulatedBlend = _blendBuilder.BlendState(blendStateBuilder .ResetTo(GorgonBlendState.Default) .DestinationBlend(alpha: Blend.One) .Build()) .Build(); _drawAdditiveBlend = _blendBuilder.BlendState(blendStateBuilder .ResetTo(GorgonBlendState.Additive) .DestinationBlend(alpha: Blend.One) .Build()) .Build(); _drawNoBlend = _blendBuilder.BlendState(blendStateBuilder .ResetTo(GorgonBlendState.NoBlending) .DestinationBlend(alpha: Blend.One) .Build()) .Build(); GorgonApplication.IdleMethod = Gorgon_Idle; } catch (ReflectionTypeLoadException refEx) { string refErr = string.Join("\n", refEx.LoaderExceptions.Select(item => item.Message)); GorgonDialogs.ErrorBox(this, refErr); } catch (Exception ex) { GorgonExample.HandleException(ex); GorgonApplication.Quit(); } }
/// <summary> /// Function to initialize the application. /// </summary> private static void Initialize() { try { // Create our form. _mainForm = GorgonExample.Initialize(new DX.Size2(Settings.Default.Resolution.Width, Settings.Default.Resolution.Height), "Boinger"); // Add a keybinding to switch to full screen or windowed. _mainForm.KeyDown += _mainForm_KeyDown; // Set up the swap chain, buffers, and texture(s). InitializeGpuResources(); // Create our planes. // Here's where we create the 2 planes for our rear wall and floor. We set the texture size to texel units because that's how the video card expects // them. However, it's a little hard to eyeball 0.67798223f by looking at the texture image display, so we use the ToTexel function to determine our // texel size. DX.Size2F textureSize = _texture.ToTexel(new DX.Size2(511, 511)); // And here we set up the planes with a material, and initial positioning. _planes = new[] { new Plane(_graphics, _inputLayout, new DX.Vector2(3.5f), new DX.RectangleF(0, 0, textureSize.Width, textureSize.Height)) { Material = new Material { Diffuse = GorgonColor.White, Texture = _texture }, Position = new DX.Vector3(0, 0, 3.0f) }, new Plane(_graphics, _inputLayout, new DX.Vector2(3.5f), new DX.RectangleF(0, 0, textureSize.Width, textureSize.Height)) { Material = new Material { Diffuse = GorgonColor.White, Texture = _texture }, Position = new DX.Vector3(0, -3.5f, 3.5f), Rotation = new DX.Vector3(90.0f, 0, 0) } }; // Create our sphere. // Again, here we're using texels to align the texture coordinates to the other image packed into the texture (atlasing). DX.Vector2 textureOffset = _texture.ToTexel(new DX.Vector2(516, 0)); // This is to scale our texture coordinates because the actual image is much smaller (255x255) than the full texture (1024x512). textureSize = _texture.ToTexel(new DX.Size2(255, 255)); // Give the sphere a place to live. _sphere = new Sphere(_graphics, _inputLayout, 1.0f, textureOffset, textureSize) { Position = new DX.Vector3(2.2f, 1.5f, 2.5f), Material = new Material { Diffuse = GorgonColor.White, Texture = _texture } }; // Initialize the states used to draw the objects. InitializeStates(); // Initialize 2D rendering. _2D = new Gorgon2D(_graphics); // I know, there's a lot in here. Thing is, if this were Direct 3D 11 code, it'd probably MUCH // more code and that's even before creating our planes and sphere. } finally { GorgonExample.EndInit(); } }
/// <summary> /// Raises the <see cref="E:System.Windows.Forms.Form.Load" /> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs" /> that contains the event data.</param> protected override void OnLoad(EventArgs e) { base.OnLoad(e); Cursor.Current = Cursors.WaitCursor; try { GorgonExample.ResourceBaseDirectory = new DirectoryInfo(Settings.Default.ResourceLocation); // Load the custom codec. if (!LoadCodec()) { GorgonDialogs.ErrorBox(this, "Unable to load the image codec plug in."); GorgonApplication.Quit(); return; } // Set up the graphics interface. // Find out which devices we have installed in the system. IReadOnlyList <IGorgonVideoAdapterInfo> deviceList = GorgonGraphics.EnumerateAdapters(); if (deviceList.Count == 0) { GorgonDialogs.ErrorBox(this, "There are no suitable video adapters available in the system. This example is unable to continue and will now exit."); GorgonApplication.Quit(); return; } _graphics = new GorgonGraphics(deviceList[0]); _swap = new GorgonSwapChain(_graphics, this, new GorgonSwapChainInfo("Codec PlugIn SwapChain") { Width = ClientSize.Width, Height = ClientSize.Height, Format = BufferFormat.R8G8B8A8_UNorm }); _graphics.SetRenderTarget(_swap.RenderTargetView); // Load the image to use as a texture. IGorgonImageCodec png = new GorgonCodecPng(); _image = png.LoadFromFile(Path.Combine(GorgonExample.GetResourcePath(@"Textures\CodecPlugIn\").FullName, "SourceTexture.png")); GorgonExample.LoadResources(_graphics); ConvertImage(); GorgonApplication.IdleMethod = Idle; } catch (Exception ex) { GorgonExample.HandleException(ex); GorgonApplication.Quit(); } finally { Cursor.Current = Cursors.Default; } }